AngularAMD + UI路由器+动态控制器的名字吗? [英] AngularAMD + ui-router + dynamic controller name?

查看:613
本文介绍了AngularAMD + UI路由器+动态控制器的名字吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写我的应用程序的通用途径,解决基于路径PARAMS动态视图和控制器的名称。

我有以下的code的作品:

  $ stateProvider.state(默认,angularAMD.route({
    网址:'/:模块/:动作ID,    templateUrl:功能(PARAMS){
        VAR模块= params.module;
        VAR行动=模块+ params.action.charAt(0).toUpperCase()
                            + params.action.substr(1);        返回应用程序/视图/+模块+/+动作+'View.html';
    },    控制器:'UserController的,
}));

不过,我无法想出一个办法来解决动态控制器名称。我试着用决心描述 here,但UI路由器似乎不同的方式处理解决比角路线。

任何指针?

修改:我使用已经尝试过 controllerProvider ,但它不为我工作(例如,下列code只返回一个硬codeD控制器的名字来测试其是否实际工作):

  controllerProvider:功能(){
    回报UserController的';
}

给我以下错误:


  

错误:[NG:AREQ]参数'UserController的不是一个函数,得到了不确定
  <$c$c>http://errors.angularjs.org/1.3.3/ng/areq?p0=userController&p1=not%20aNaNunction%2C%20got%20undefined



解决方案

这是的工作plunker

解决方案

我们需要的UI路由器的两个特点:


  • 决心的(加载JS code的缺件)

  • controllerProvider(见从下面的文件列举了)

angularAMD - main.js定义

这将是我们main.js,其中包含智能转换controllerName - controllerPath:

  require.config({    //的baseUrl:JS /脚本
    的baseUrl:,    //别名库的路径
    路径:{
        角度:角,
        UI路由器:角UI路由器
        angularAMD:angularAMD,        DefaultCtrl:Controller_Default,
        OtherCtrl:Controller_Other,
    },    垫片:{
        angularAMD:角],
        UI路由器:[角],
    },    DEPS:['应用']
});

控制器:

  // Controller_Default.js
定义(['应用'],功能(应用程序){
    app.controller('DefaultCtrl',函数($范围){
        $ scope.title =从默认的;
    });
});// Controller_Other.js
定义(['应用'],功能(应用程序){
    app.controller('OtherCtrl',函数($范围){
        $ scope.title =其他;
    });
});

app.js

首先,我们需要一些方法的参数(如ID)转换成控制器名称。对于我们的测试目的,让我们用这个天真的实现:

  VAR controllerNameByParams =功能($ stateParams)
{
    动态控制器名称采矿//简单的例子
    //从传入状态PARAMS    VAR控制器=OtherCtrl;    如果($ stateParams.id === 1){
        控制器=DefaultCtrl;
    }    返回控制器;
}

.STATE()

这将是我们的最终状态定义

  $ stateProvider
    .STATE(默认,angularAMD.route({
        网址:/ {ID:INT},
        templateProvider:函数($ stateParams)
        {
            如果($ stateParams.id === 1)
            {
                回归&LT; D​​IV&GT; ONE - 喂的{{title}}&LT; / DIV&gt;中;
            }
            回归&LT; D​​IV&GT;二 - 喂的{{title}}&LT; / DIV&gt;中;
        },
        解析:{
            loadController:['$ Q','$ stateParams',
                功能($ Q $ stateParams)
                {
                    //获取控制器名称===这里作为Controller_Name.js路径
                    //这是设置在main.js路径{}
                    VAR controllerName = controllerNameByParams($ stateParams);                    变种推迟= $ q.defer();
                    需要([controllerName]功能(){deferred.resolve();});
                    返回deferred.promise;
                }]
        },
        controllerProvider:函数($ stateParams)
        {
            //获取控制器名称===这里作为一个动态控制器名称
            VAR controllerName = controllerNameByParams($ stateParams);
            返回controllerName;
        },
    }));

检查在这里,在这个工作的例子

文件

由于记录在这里: $ stateProvider ,为状态(姓名,stateConfig)我们可以使用控制器 controllerProvider 。从文档的一些提取物:

controllerProvider

...

控制器 (可选)的stringFunction中


  应该与新近的相关范围,或者作为字符串传递的注册控制器的名称关联

控制器FN。任选地,ControllerAs可以这里声明


 控制器:MyRegisteredController控制器:
MyRegisteredController为fooCtrl}控制器:函数($范围,为MyService){
$ scope.data = MyService.getData(); }

controllerProvider (可选)的功能


  

这是返回的实际控制人或字符串注射提供商的功能。


  controllerProvider:
  功能(MyResolveData){
    如果(MyResolveData.foo)
      返回FooCtrl
    否则,如果(MyResolveData.bar)
      返回BarCtrl
    否则返回函数($范围){
      $ scope.baz =Qux;
    }
  }

...

的决心

解析 (可选)的对象


  

这是可选的地图&LT;字符串函数&GT; 应该被注入控制器的依赖。 如果这些依赖关系都承诺路由器将等待他们所有待解决之前的控制器被实例化...


即。让我们使用 controllerProvider


  

...动态解析控制器名称...


在的情况下,你设法到达这里,也许你想检查与RequireJS另一个类似的解决方案 - 角-ui-路由器requirejs,控制器的延迟加载

I'm trying to write a generalized route in my application and resolve the view and controller names on the fly based on the route params.

I have the following code that works:

$stateProvider.state('default', angularAMD.route({
    url: '/:module/:action?id',

    templateUrl: function (params) {
        var module = params.module;
        var action = module + params.action.charAt(0).toUpperCase() 
                            + params.action.substr(1);

        return 'app/views/' + module + '/' + action + 'View.html';
    },

    controller: 'userController',
}));

However, I'm unable to figure out a way to resolve the controller name dynamically. I tried using resolve as described here, but ui-router seems to handle resolve differently than angular-route.

Any pointers?

EDIT: I've already tried using controllerProvider but it doesn't work for me (for instance, the following code just returns a hard coded controller name to test whether it actually works):

controllerProvider: function () {
    return 'userController';
}

Gives me the following error:

Error: [ng:areq] Argument 'userController' is not a function, got undefined http://errors.angularjs.org/1.3.3/ng/areq?p0=userController&p1=not%20aNaNunction%2C%20got%20undefined

解决方案

This is a link to working plunker.

solution

We need two features of the UI-Router:

  • resolve (to load the missing pieces of js code)
  • controllerProvider (see cites from documentation below)

angularAMD - main.js definition

This would be our main.js, which contains smart conversion controllerName - controllerPath:

require.config({

    //baseUrl: "js/scripts",
    baseUrl: "",

    // alias libraries paths
    paths: {
        "angular": "angular",
        "ui-router": "angular-ui-router",
        "angularAMD": "angularAMD",

        "DefaultCtrl": "Controller_Default",
        "OtherCtrl": "Controller_Other",
    },

    shim: {
        "angularAMD": ["angular"],
        "ui-router": ["angular"],
    },

    deps: ['app']
});

controllers:

// Controller_Default.js
define(['app'], function (app) {
    app.controller('DefaultCtrl', function ($scope) {
        $scope.title = "from default"; 
    });
}); 

// Controller_Other.js
define(['app'], function (app) {
    app.controller('OtherCtrl', function ($scope) {
        $scope.title = "from other";
    });
});

app.js

Firstly we would need some method converting the param (e.g. id) into controller name. For our test purposes let's use this naive implementation:

var controllerNameByParams = function($stateParams)
{
    // naive example of dynamic controller name mining
    // from incoming state params

    var controller = "OtherCtrl";

    if ($stateParams.id === 1) {
        controller = "DefaultCtrl";
    }

    return controller;
}

.state()

And that would be finally our state definition

$stateProvider
    .state("default", angularAMD.route({
        url: "/{id:int}",
        templateProvider: function($stateParams)
        {
            if ($stateParams.id === 1)
            {
                return "<div>ONE - Hallo {{title}}</div>";
            }
            return "<div>TWO - Hallo {{title}}</div>";
        },
        resolve: {
            loadController: ['$q', '$stateParams',
                function ($q, $stateParams)
                {
                    // get the controller name === here as a path to Controller_Name.js
                    // which is set in main.js path {}
                    var controllerName = controllerNameByParams($stateParams);

                    var deferred = $q.defer();
                    require([controllerName], function () { deferred.resolve(); });
                    return deferred.promise;
                }]
        },
        controllerProvider: function ($stateParams)
        {
            // get the controller name === here as a dynamic controller Name
            var controllerName = controllerNameByParams($stateParams);
            return controllerName;
        },
    }));

Check it here, in this working example

documentation

As documented here: $stateProvider, for a state(name, stateConfig) we can use controller and controllerProvider. Some extract from documentation:

controllerProvider

...

controller (optional) stringfunction

Controller fn that should be associated with newly related scope or the name of a registered controller if passed as a string. Optionally, the ControllerAs may be declared here.

controller: "MyRegisteredController"

controller:
"MyRegisteredController as fooCtrl"}

controller: function($scope, MyService) {
$scope.data = MyService.getData(); }

controllerProvider (optional) function

Injectable provider function that returns the actual controller or string.

controllerProvider:
  function(MyResolveData) {
    if (MyResolveData.foo)
      return "FooCtrl"
    else if (MyResolveData.bar)
      return "BarCtrl";
    else return function($scope) {
      $scope.baz = "Qux";
    }
  }

...

resolve

resolve (optional) object

An optional map<string, function> of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them ALL to be resolved before the controller is instantiated...

I.e. let's use controllerProvider:

... to resolve the controller name dynamically...

In case, that you managed to get here, maybe you'd like to check another similar solution with RequireJS - angular-ui-router with requirejs, lazy loading of controller

这篇关于AngularAMD + UI路由器+动态控制器的名字吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆