GVKun编程网logo

AngularJS UI-Router:在加载应用程序之前预加载$http数据(angularjs页面加载后再执行)

13

在本文中,我们将带你了解AngularJSUI-Router:在加载应用程序之前预加载$http数据在这篇文章中,我们将为您详细介绍AngularJSUI-Router:在加载应用程序之前预加载$ht

在本文中,我们将带你了解AngularJS UI-Router:在加载应用程序之前预加载$http数据在这篇文章中,我们将为您详细介绍AngularJS UI-Router:在加载应用程序之前预加载$http数据的方方面面,并解答angularjs页面加载后再执行常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的Angular2 router.navigate重新加载应用程序、AngularJS - 利用 ui-route 及 provider 实现页面数据预加载的关键、angularjs ui-router-如何建立跨应用程序全局的主状态、AngularJS ui-router:reload:true也重新加载父状态

本文目录一览:

AngularJS UI-Router:在加载应用程序之前预加载$http数据(angularjs页面加载后再执行)

AngularJS UI-Router:在加载应用程序之前预加载$http数据(angularjs页面加载后再执行)

我需要使用ui-router插件的AngularJS专家的帮助.有些人可以提供一个plunker示例,可以在app运行之前预加载$http数据请求吗?

我做了一些研究,但最接近的是这两个堆栈溢出:

AngularJS: How to load json feed before app load?

Delaying AngularJS route change until model loaded to prevent flicker

我不到一个星期就进入angularJS,所以任何帮助都将不胜感激.

解决方法

从 https://github.com/angular-ui/ui-router/wiki#resolve起

您可以使用resolve为控制器提供自定义状态的内容或数据. resolve是一个可选的依赖关系图,应该注入控制器.

如果这些依赖项中的任何一个是promise,它们将在实例化控制器并触发$routeChangeSuccess事件之前被解析并转换为值.

resolve属性是一个map对象. map对象包含键/值对:

> key – {string}:要注入控制器的依赖项的名称.
> factory – {string | function}:

>如果是string,则它是服务的别名.
>否则,如果是函数,则将其注入,并将返回值视为依赖项.如果结果是promise,则在实例化控制器并将其值注入控制器之前解析.

例子:

在实例化控制器之前,必须解析下面解决的每个对象(通过deferred.resolve(),如果它们是一个promise).注意每个解析对象如何作为参数注入控制器.

$stateProvider.state('myState',{
    resolve: {

        // Example using function with simple return value.
        // Since it's not a promise,it resolves immediately.
        simpleObj: function () {
            return { value: 'simple!' };
        },// Example using function with returned promise.
        // This is the typical use case of resolve.
        // You need to inject any services that you are
        // using,e.g. $http in this example
        promiSEObj: function ($http) {
            // $http returns a promise for the url data
            return $http({ method: 'GET',url: '/someUrl' });
        },// Another promise example. If you need to do some 
        // processing of the result,use .then,and your 
        // promise is chained in for free. This is another
        // typical use case of resolve.
        promiSEObj2: function ($http) {
            return $http({ method: 'GET',url: '/someUrl' })
               .then(function (data) {
                   return doSomeStuffFirst(data);
               });
        },// Example using a service by name as string.
        // This would look for a 'translations' service
        // within the module and return it.
        // Note: The service Could return a promise and
        // it would work just like the example above
        translations: "translations",// Example showing injection of service into
        // resolve function. Service then returns a
        // promise. Tip: Inject $stateParams to get
        // access to url parameters.
        translations2: function (translations,$stateParams) {
            // Assume that getLang is a service method
            // that uses $http to fetch some translations.
            // Also assume our url was "/:lang/home".
            translations.getLang($stateParams.lang);
        },// Example showing returning of custom made promise
        greeting: function ($q,$timeout) {
            var deferred = $q.defer();
            $timeout(function () {
                deferred.resolve('Hello!');
            },1000);
            return deferred.promise;
        }
    },// The controller waits for every one of the above items to be
    // completely resolved before instantiation. For example,the
    // controller will not instantiate until promiSEObj's promise has 
    // been resolved. Then those objects are injected into the controller
    // and available for use.  
    controller: function ($scope,simpleObj,promiSEObj,promiSEObj2,translations,translations2,greeting) {
        $scope.simple = simpleObj.value;

        // You can be sure that promiSEObj is ready to use!
        $scope.items = promiSEObj.items;
        $scope.items = promiSEObj2.items;

        $scope.title = translations.getLang("english").title;
        $scope.title = translations2.title;

        $scope.greeting = greeting;
    }
})

Angular2 router.navigate重新加载应用程序

Angular2 router.navigate重新加载应用程序

我在我的应用程序中定义了以下路由…
app.components.ts
@RouteConfig([
  {path:'/employees/...',name:'Employees',component:EmployeeComponent},...

employee.component.ts
@RouteConfig([
  {path:'/',name:'EmployeeList',component:EmployeeListComponent,useAsDefault: true},{path:'/:id',name:'EmployeeDetail',component:EmployeeDetailComponent}
])

当我从EmployeeDetailComponent模板路由时……

<button[routerLink]="['EmployeeList']">Close</button>

应用程序按预期路由到员工列表页面.

但是,当我使用router.navigate进行路由时……

// template
<button(click)="save()">Save</button>

// EmployeeDetailComponent
saveEmployee() {
  this._employeeServer.updateEmployee(this.employee);
  this._router.navigate(['EmployeeList']);
}

应用程序路由员工列表(如预期的那样),然后,片刻之后,应用程序完全重新加载(不像预期的那样).

知道为什么router.navigate的行为与routerLink不同吗?我错过了什么?

你可以使用这个指令:
@Directive({
  selector: `click-stop-propagation`
  events: 'stopClick($event)'
})
class ClickStopPropagation {
  stopClick(event:Event) {
    event.preventDefault();
    event.stopPropagation();
  }
}

并以这种方式应用它:

<button(click)="save()" click-stop-propagation>Save</button>

另一种解决方案是将事件传递给save方法:

<button(click)="save($event)" click-stop-propagation>Save</button>

并用它来阻止事件传播:

save(event) {
  this._employeeServer.updateEmployee(this.employee);
  this._router.navigate(['EmployeeList']);
  event.preventDefault();
  event.stopPropagation();
}

AngularJS - 利用 ui-route 及 provider 实现页面数据预加载的关键

AngularJS - 利用 ui-route 及 provider 实现页面数据预加载的关键

我在使用 angular 的时候经常碰到一个问题,希望在必要数据加载完成之前暂时不要显示页面。这时,我一般用 ui-routeresolve 功能并结合数据接口来实现。(数据 api 我是一般用 provider 来封装)

首先,在 config 中注入 testProvider,并非必须,只是演示下如何配置 provider。这里有个区别就是,在 config 中不能直接访问 provider$get 中的方法,但是可以访问 provider 对象的属性与方法。(比如下面代码中的 this.setPrefix 方法)

其次,然后回到我的需求部分,在 ui-route 里面获取需要预先加载的数据。这个跟 controller 中的注入没有区别,如例子只要在 resolve.userInfo 的方法参数上添加自己需要的 provider 名称,这里就是 test,这样我们就可以直接调用 test.current 了。resolve 也是一个关键,我们用它来获取数据并注入到 controller 中。

最后,在 controller 里面注入我们需要使用的数据,userInfo

angular.module(''logging'', [])
    .provider("test", function() {
        var prefix;
        this.setPrefix = function(p) {
            prefix = p;
        }

        this.$get = function() {
            return {
                log: function(msg) {
                    console.log(prefix,msg);
                },
                current:function(){
                	return {"name":"JMZ"};
                }
            }
        }
    })

angular.module(''myApp'', [''logging'']).config(["$stateProvider", "testProvider" function ($stateProvider, testProvider) {
    testProvider.setPrefix("works: ");

    $stateProvider.state("home/index", {
        url: "/",
        "templateUrl": "home/index.tpl.html",
        "controller": "home/index.ctrl"
        resolve: {
            userInfo: function ($q,test) {
                return test.current();
            }
        }
    });

}]).controller("myCtrl", ["$scope","test","userInfo",function($scope, test,userInfo) {
    test.log(userInfo);    
    $scope.$watch(''myModel'', function(newval) {
        test.log(newval);
    }]);
});

angularjs ui-router-如何建立跨应用程序全局的主状态

angularjs ui-router-如何建立跨应用程序全局的主状态

<html ng-app="app"><head>...</head><body>  <div id="header"></div>  <div id="notification"></div>  <div id="container"></div>  <div id="footer"></div></body></html>

使用应用程序的给定结构(源自angular-app):

  • 标头:这里是网站导航,登录/退出工具栏等。它是动态的,具有自己的控制器
  • notification:全局通知容器。
  • 容器:这曾经是我的<ng-view>。这就是所有其他模块的加载位置。
  • 页脚:全局页脚。

状态层次结构如何?我已经看过了显示单个模块(联系人)的示例,但是通常一个应用程序将具有全局(根)状态,而在根状态内部则呈现其他模块状态。

我在想的是我的app模块可能具有root状态,然后每个模块都应该具有其自己的状态,而我必须从状态 继承root。我对吗?

同样从ui-state示例中,它们既使用了$routeProvider$urlRouterProvider$stateProvider定义了url。我的理解是$stateProvide还处理路由。如果输入错误,应该使用哪个提供商进行路由?

编辑
:http://plnkr.co/edit/wqKsKwFq1nxRQ3H667LU?p
= preview

谢谢!

答案1

小编典典

您采用的方法很接近。@ ben-
schwartz的解决方案演示了如何在根状态下为三个基本静态的视图设置默认值。缩孔工具中缺少的是您的孩子仍然需要引用顶部容器视图。

   .state(''root'',{      url: '''',      views: {        ''header'': {          templateUrl: ''header.html'',          controller: ''HeaderCtrl''        },        ''footer'':{          templateUrl: ''footer.html''        }      }    })    .state(''root.about'', {      url: ''/about'',      views: {        ''container@'': {          templateUrl: ''about.html''        }      }    });

请注意views: { ''container@'': ...},而不是只templateUrl: ...''root.about''

您可能还想问的是,是否可以让模块定义自己的状态集,然后将其附加到应用程序的状态层次结构中。每个模块提供的路由/状态的一种即插即用功能。

为此,您需要将模块紧密耦合到主应用程序。

在模块中:

angular.module(''contact'', [''ui.router''])  .constant(''statesContact'', [      { name: ''root.contact'',        options: {          url: ''contact'',          views: {            ''container@'': {              templateUrl: ''contacts.html''            }          },          controller:''ContactController''      }}    ])  .config([''$stateProvider'', function($stateProvider){      }])

然后,在应用程序中:

var app = angular.module(''plunker'', [''ui.router'', ''contact'']);app.config(       [''$stateProvider'', ''statesContact'',            function($stateProvider,   statesContact){    $stateProvider    .state(''root'',{ ... })    .state(''root.home'', { ... })    .state(''root.about'', { ... })    angular.forEach(statesContact, function(state) {      $stateProvider.state(state.name, state.options);    })      }]);

这意味着您的所有模块都需要与您的应用程序中设置的这种模式兼容。但是,如果您接受此约束,则可以选择包括模块的任何组合,并且它们的状态会 神奇地
添加到您的应用程序中。如果您想变得更高级,可以state.options.urlstatesModuleName循环中进行修改,例如为模块的url结构添加前缀。

还要注意的是,模块ui.compat只需要当你 转换
$routeProvider$stateProvider。通常应ui.state改为使用。

另外,请不要忘记在header.html中进行调整$state.includes(''root.contact'')

更新的插头

AngularJS ui-router:reload:true也重新加载父状态

AngularJS ui-router:reload:true也重新加载父状态

In this plunk你有两个ui-router状态,一个父母和一个孩子.通过单击链接调用子项时,因为它具有reload:true选项,所以它总是被重新加载.这很好,但问题是父状态也被重新加载.尝试多次单击“填充11”链接,您将看到父时间戳也发生变化.

我怎样才能重新加载孩子?

使用Javascript:

var app = angular.module("app",['ui.router']);

app.config(function($stateProvider,$urlRouterProvider) {

  $urlRouterProvider.otherwise("/");

  $stateProvider
    .state('state1',{
          templateUrl: 'state1.html',controller: function($scope) {

            $scope.theTime1 = Date.Now();

          }
    })
    .state('state1.state11',{
          templateUrl: 'state11.html',controller: function($scope) {

               $scope.theTime11 = Date.Now();

         }
    });

});
它实际上非常简单.

不要使用重新加载,因为这完全是您找到的.它重新加载路线的一切.

而是在子路径中添加一个参数,每次单击链接时都要确保更改该参数.这将迫使子状态重新加载.

我用一个例子更新了你的插件.我刚刚添加了一个num参数,并在每次单击链接时增加count变量.

http://plnkr.co/edit/qTA39rrYFYUegzuFbWnc?p=preview

今天关于AngularJS UI-Router:在加载应用程序之前预加载$http数据angularjs页面加载后再执行的分享就到这里,希望大家有所收获,若想了解更多关于Angular2 router.navigate重新加载应用程序、AngularJS - 利用 ui-route 及 provider 实现页面数据预加载的关键、angularjs ui-router-如何建立跨应用程序全局的主状态、AngularJS ui-router:reload:true也重新加载父状态等相关知识,可以在本站进行查询。

本文标签: