【问题标题】:Trying to Dynamically set a templateUrl in controller based on constant尝试基于常量在控制器中动态设置模板Url
【发布时间】:2015-03-02 16:21:12
【问题描述】:

我想根据我在 angularjs 引导程序中定义的预设常量更改与控制器关联的 templateUrl。我不知道如何改变它。我已经尝试过 UrlRouteProvider,但无法弄清楚如何使用它从文件系统中提取 html。我卡在 templateUrl 上。

在下面的代码中,输出首先显示“svcc 确实传入了第一个函数的console.out,但是在templateUrl 定义函数中,CONFIG 是未定义的。

我愿意接受其他方式来做到这一点。

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

    var myConstant = {};
    myConstant.codeCampType = "svcc";
    app.constant("CONFIG", myConstant);

    app.config(['$stateProvider', '$urlRouterProvider','CONFIG',
        function ($stateProvider, $urlRouterProvider,CONFIG) {
            console.log(CONFIG.codeCampType);
            $stateProvider
                .state('home', {
                    url: '/home',
                    //templateUrl: 'index5templateA.html',   (THIS WORKS)
                    templateUrl: function(CONFIG) {
                        console.log('in templateUrl ' + CONFIG.codeCampType);
                        if (CONFIG.codeCampType === "svcc") {
                            return 'index5templateA.html';
                        } else {
                            return 'index5templateB.html';
                        }
                    },
                    controller: function ($state) {
                    }
                });
        }]);

【问题讨论】:

    标签: angularjs angular-ui-router


    【解决方案1】:

    我必须添加另一个答案,与 angular 1.3 的全新功能有关

    $templateRequest

    $templateRequest 服务使用$http 下载提供的模板,并在成功后将内容存储在$templateCache 中。

    用法

    $templateRequest(tpl, [ignoreRequestError]);
    

    参数 - tpl 字符串 - HTTP 请求模板 URL

    • ignoreRequestError (optional) boolean - 请求失败或模板为空时是否忽略异常

    还有updated plunker

    templateProvider: function(CONFIG, $templateRequest) {
        console.log('in templateUrl ' + CONFIG.codeCampType);
    
        var templateName = 'index5templateB.html';
    
        if (CONFIG.codeCampType === "svcc") {
             templateName = 'index5templateA.html';
        } 
    
        return $templateRequest(templateName);
    },
    

    【讨论】:

      【解决方案2】:

      我创建了一个plunker here 你快到了,只是语法是 'templateProvider':

      .state('home', {
          url: '/home',
          //templateUrl: 'index5templateA.html',   (THIS WORKS)
          // templateUrl: function(CONFIG) {
          templateProvider: function(CONFIG) {
          ...
      

      来自文档的片段:

      Templates

      模板网址
      ... templateUrl 也可以是返回 url 的函数。 它需要一个预设参数stateParams,不注入。

      模板提供者
      或者您可以使用 模板提供程序 函数,该函数可以注入,可以访问本地,并且必须返回模板 HTML,如下所示:

      所以在我们的例子中,这将是实现:

       $stateProvider
          .state('home', {
              url: '/home',
              //templateUrl: 'index5templateA.html',   (THIS WORKS)
              templateProvider: function(CONFIG, $http, $templateCache) {
                  console.log('in templateUrl ' + CONFIG.codeCampType);
                  
                  var templateName = 'index5templateB.html';
                  
                  if (CONFIG.codeCampType === "svcc") {
                       templateName = 'index5templateA.html';
                  } 
                  var tpl = $templateCache.get(templateName);
                  
                  if(tpl){
                    return tpl;
                  }
                  
                  return $http
                     .get(templateName)
                     .then(function(response){
                        tpl = response.data
                        $templateCache.put(templateName, tpl);
                        return tpl;
                    });
              },
              controller: function ($state) {
              }
          });
      

      查看examle here

      同时检查:

      【讨论】:

      • 感谢 Radim。我确实看到了这两个帖子,但我觉得我不是那么接近。使用 $http 获取模板并缓存它们真的让我很困惑。如果我要返回一个模板而不是 templateUrl,我想我就快到了。我觉得如果 $templateFactory.fromUrl 工作我会在那里,但该提供者似乎不再存在。
      • 太着急了...抱歉...我创建了 plunker,它应该显示如何处理缓存和 $http 并且...请查看最新链接...请跨度>
      • 感谢 Radim。您在其中设置 $rootScope 的功能是否必要?您的解决方案很优雅。非常感谢,我所希望的。
      • No no ;) ;) 我通常在我的工具带中有一些启动脚本...以便尽快创建 plunker。 ;) 那只是...享受强大的 UI-Router
      【解决方案3】:
       var app = angular.module('svccApp', [
              'ui.router'
          ]);
      
          var myConstant = {};
          myConstant.codeCampType = "svcc";
      
          app.config(['$stateProvider', '$urlRouterProvider','CONFIG',
              function ($stateProvider, $urlRouterProvider,CONFIG) {
                  console.log(CONFIG.codeCampType);
                  $stateProvider
                      .state('home', {
                          url: '/home',
                          //templateUrl: 'index5templateA.html',   (THIS WORKS)
                          templateUrl: function() {
                              if (myConstant.codeCampType === "svcc") {
                                  return 'index5templateA.html';
                              } else {
                                  return 'index5templateB.html';
                              }
                          },
                          controller: function ($state) {
                          }
                      });
              }]);
      

      【讨论】:

      • 当我测试这个时,我似乎无法访问函数中的 myConstant
      • 你会的。 app.config 将关闭 myConstant。您正在将 myConstant 创建为全局变量。当您的 templateUrl 函数将执行时,您将拥有 myConstant。
      • 当我运行它时你显然是对的,但我很困惑。在我的示例中,它似乎不是全局的,但在您的示例中却是。我不明白什么? -谢谢
      • 请忽略我最后的评论。我现在明白了。 stackoverflow.com/questions/4862193/javascript-global-variables
      猜你喜欢
      • 2019-03-18
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多