javascript - 用户界面路由器 : async data in templateUrl function

标签 javascript angularjs angular-ui-router promise angular-promise

我在 ui 路由器方面遇到了一个相当新奇的问题。我基本上是在尝试在 API 中查询模板 url,该模板 url 作为 Resource 对象存储和返回。问题是 templateUrl 函数似乎返回为未定义。我的代码如下:

(function() {
    'use strict';

  angular.module('myApp')
    .config(function ($stateProvider, PageProvider, $httpProvider) {
      $stateProvider
        .state('core', {
          abstract: true,
          templateUrl: 'app/core/core.index.html',
          controller: 'CoreController',
          controllerAs: 'vm'
        })
        /* Parent page view */
        .state('core.page', {
          url: '/:slug',
          views: {
            'page_content@core': {
              templateUrl: function(params) {
                var slug = params.slug;
                // only need to load core template
                var url = 'assets/templates/' + slug + '.html';

                return url;
              },
              controller: 'PageController',
              controllerAs: 'vm'
            }
          }
        })
        .state('core.page.child', {
          url: '/:child',
          views: {
            'page_content@core': {
              templateUrl: function($stateParams) {
                PageProvider
                  .$get() // $get() returns Page service
                  .findOne($stateParams.child)
                  .$promise
                  .then(function(data){
                    return data.template.url;
                  });
              }
            }
          }
        });
      });
})();

我为我的状态“core.page.child”设置了一个断点,以查看范围内有哪些变量可用,然后我发现了一些非常奇怪的东西:

url here is undefined...

but it logs out the correct templateUrl value from the promise

我真的不明白为什么会发生这种情况,因为 .then(cb) 仅在 promise 解决后才被调用,这意味着它应该按预期返回正确的值 - 但它没有't。

任何帮助将不胜感激。

编辑:我应该补充一点,正在发生的事情是 ui-router 根本没有加载我的模板 - 我得到一个空的 ui-view。我最初以为这可能是我的 $stateProvider 配置的问题,但事实似乎并非如此。

Edit2:我根据调用堆栈深入研究了源代码。看来你们俩都是对的 - ui-router 不能与 Promise 一起工作。

/**
 * @ngdoc function
 * @name ui.router.util.$templateFactory#fromConfig
 * @methodOf ui.router.util.$templateFactory
 *
 * @description
 * Creates a template from a configuration object. 
 *
 * @param {object} config Configuration object for which to load a template. 
 * The following properties are search in the specified order, and the first one 
 * that is defined is used to create the template:
 *
 * @param {string|object} config.template html string template or function to 
 * load via {@link ui.router.util.$templateFactory#fromString fromString}.
 * @param {string|object} config.templateUrl url to load or a function returning 
 * the url to load via {@link ui.router.util.$templateFactory#fromUrl fromUrl}.
 * @param {Function} config.templateProvider function to invoke via 
 * {@link ui.router.util.$templateFactory#fromProvider fromProvider}.
 * @param {object} params  Parameters to pass to the template function.
 * @param {object} locals Locals to pass to `invoke` if the template is loaded 
 * via a `templateProvider`. Defaults to `{ params: params }`.
 *
 * @return {string|object}  The template html as a string, or a promise for 
 * that string,or `null` if no template is configured.
 */
this.fromConfig = function (config, params, locals) {
  return (
    isDefined(config.template) ? this.fromString(config.template, params) :
    isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
    isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, locals) :
    null
  );
};

看来我要么必须使用 $stateProvider.decorator,要么破解 ui-router 的核心。我想我可能会选择后者并提交 PR。我也会将此问题发布到 github 存储库上,看看 ui-router 团队中是否有人可以解决此问题。

最佳答案

Working plunk

您可以使用 resolvetemplateProvider 来执行此操作。

  .state('child', {
      url: '/:child',
      resolve: {
        childTemplate: function ($stateParams, $templateRequest) {
          return $templateRequest($stateParams.child + ".html");
        }
      },
      templateProvider: function(childTemplate) { 
        return childTemplate;
      }
  });

这将创建一个解析,它使用 $stateParams 来获取模板(我使用 $templateRequest 来获取,添加到 $templateCache,并将内容全部返回)。然后,解析后的模板内容被注入(inject)到 View 的templateProvider中。

关于javascript - 用户界面路由器 : async data in templateUrl function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30964498/

相关文章:

javascript - rails +jQuery : Get the Value of an Item Inside a Table to Use in a Prepend Function

javascript - HTML表格中的隐藏行导致问题

javascript - 您可以在获得客户许可的情况下使用 javascript 访问客户的书签吗?

javascript - 类体之外不允许使用 "this"关键字

javascript - 如何在 Angular Directive(指令)中正确显示json

angularjs - 如果在 Angular.js 1.6.5 和 angular-ui-router 0.4.1.3 中单独保存在同一个文件中,回调函数是否会更改作用域?

AngularJS 与 Angular-ui-router 和 jQuery-File-Upload

javascript - 在 Angular 1 中更改正文标签类

javascript - 将数据从 Controller 发送到js函数

html - AngularJS 的 Internet Explorer 背景位置和背景大小