13

我正在使用 ng-boilerplate,并且必须根据用户配置添加在生产中使用不同模板的可能性。

.config(function config( $stateProvider ) {
 $stateProvider.state( 'demo', {
    url: '/demo',
    views: {
      "main": {
        controller: 'DemoCtrl',
        templateUrl: 'demo/demo.tpl.html'
      }
    }
  });
})

我目前的想法是使 templateUrl 动态化

templateUrl: 'demo/demo'+userService.getTemplate()+'.tpl.html'

并具有多个模板文件,例如:

  • demo.tpl.html(默认)
  • demo.b.tpl.html(版本 b)
  • demo.c.tpl.html(版本 c)

而 userService 函数确实提供了要使用的模板版本,例如“.b”

你同意?是否有更好/更简单的方法来解决这个问题?

4

4 回答 4

11

AngularJS 标准$routeProvider可以接受 templateUrl 的函数。但是你不能将服务注入这个函数。

ui-routertemplateProvider参数,你可以注入你想要的东西,你应该为远程模板案例返回类似这样的东西:

$stateProvider.state('demo', {
    templateProvider: function ($http, $templateCache, $stateParams, userService) {
        var url = 'demo/demo' + userService.getTemplate() + '.tpl.html';
        return $http.get(url, { cache: $templateCache }).then(function (response) {
            return response.data;
        });
    }
})
于 2013-08-27T17:48:59.163 回答
2

我不会让它继续服务,因为服务将是 js 文件的一部分。哪个是静态的(在正常情况下)

这就是我要做的,在html文件中我会放

window.abConfig = "defaultVersion";

在 app.js 我会放

.config(function config( $stateProvider ) {
 $stateProvider.state( 'demo', {
    url: '/demo',
    views: {
      "main": {
        controller: 'DemoCtrl',
        templateUrl: function() {
          return 'demo/demo' + window.abConfig + '.tpl.html';
        }
      }
    }
  });
})

它是一种 Hacky 方式,但它让我可以灵活地决定在服务器级别向用户显示哪个版本。在用户根据用户之前的活动下载内容之前,我可能需要编写逻辑,这是我无法从客户端 JavaScript 完成的。

于 2014-04-17T00:48:13.583 回答
1

这可以使用标准角度来实现,您只需从另一个角度看它!

我建议使用$templateCache。当您加载应用程序时,您可以使用所选版本的用户模板预填充 $template 缓存。

你可以做类似的事情

$templateCache.put("page-header.html", '<h1>MyAwesomeStartup</h1><h2>Buy now!?!?!</h2>');

此外,如果您不反对这个想法,您可以使用脚本标记语法将模板放入页面中,其中 id == 您在 $routeProvider 中使用的 templateURL。

<script type="text/ng-template" id="page-header.html">
  <h1>MyAwesomeStartup</h1><h2>Buy now!?!?!</h2>
</script>

ng 将直接从脚本标签加载它。

于 2013-08-29T02:02:35.110 回答
0

我有不同的方式基于相同的原则

除非您不必使用 $http 实际请求视图。

所以你可以让 ui-router 处理那部分。

当您拥有复杂的视图架构时,这会更容易。

.state('public.index', {
            url: '/',
            views: {
                "": {
                    template: '<div ui-view="abTestDummyView"></div>',
                    controller: ['landing', '$http', function(landing, $http) {
                        alert('Showing AB Test Landing #' + landing);
                        // increment landing stats
                        $http.get('http://stats.domain.com', {landing: landing});
                    }],
                    controllerAs: 'landingCtrl',
                },
                "abTestDummyView@public.index": {
                    templateProvider: ['landing', function(landing) {
                        // inject a view based on its name
                        return "<div ui-view=\"ab" + landing + "\"></div>";
                    }]
                },
                "ab1@public.index": {
                    template: "INJECTED AB1"
                    // replace by templateUrl: "/real path/"
                },
                "ab2@public.index": {
                    template: "INJECTED AB2"
                    // replace by templateUrl: "/real path/"
                }
            },
            resolve: {
                landing: function() {
                    return Math.floor((Math.random() * 2) + 1);
                }
            }
        })
于 2016-04-05T16:04:04.910 回答