AngularAMD + ui-router + 动态控制器名称? [英] AngularAMD + ui-router + dynamic controller name?

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

问题描述

我正在尝试在我的应用程序中编写一个通用路由,并根据路由参数动态解析视图和控制器名称.

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.

我有以下有效的代码:

$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',
}));

但是,我无法找到一种动态解析控制器名称的方法.我尝试使用 resolve此处所述,但 ui-router 似乎与 angular-route 处理解析不同.

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.

有什么指点吗?

EDIT:我已经尝试过使用 controllerProvider 但它对我不起作用(例如,下面的代码只返回一个硬编码的控制器名称来测试是否真的有效):

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';
}

给我以下错误:

错误:[ng:areq] 参数userController"不是函数,未定义http://errors.angularjs.org/1.3.3/ng/areq?p0=userController&p1=not%20aNaNunction%2C%20got%20undefined

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

推荐答案

这是的链接工作plunker.

我们需要 UI-Router 的两个特性:

We need two features of the UI-Router:

  • 解决(加载缺失的js代码)
  • controllerProvider(请参阅下面文档中的引用)

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

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']
});

控制器:

// 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

首先,我们需要一些方法将参数(例如 id)转换为控制器名称.为了我们的测试目的,让我们使用这个简单的实现:

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()

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

.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;
        },
    }));

在此查看,在此工作示例

如此处所述:$stateProvider,对于state(name, stateConfig),我们可以使用controllercontrollerProvider.部分文档摘录:

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

...

controller (可选) stringfunction

controller (optional) stringfunction

控制器 fn 应该与新相关的范围或已注册控制器的名称(如果作为字符串传递)相关联.或者,可以在此处声明 ControllerAs.

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 (可选) 函数

返回实际控制器或字符串的可注入提供程序函数.

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 (可选) 对象

一个可选的 map 依赖项,它应该被注入到控制器中.如果这些依赖项中的任何一个是 promises路由器将等待他们全部解决,然后再实例化控制器...

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...

即让我们使用 controllerProvider:

I.e. let's use controllerProvider:

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

如果您设法到达这里,也许您想使用 RequireJS 检查另一个类似的解决方案 - angular-ui-router 带 requirejs,控制器懒加载

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

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