【问题标题】:Angularjs directives without html in the code?代码中没有 html 的 Angularjs 指令?
【发布时间】:2014-01-15 06:55:54
【问题描述】:

我正在学习 AngularJS,但指令有点问题。我不喜欢他们的样子。具体来说,我不喜欢 javascript 中间有很多 html。看下面的例子:

myApp.directive("myDir", function() {
  return {
    restrict: "E",        // directive is an Element (not Attribute)
    scope: {              // set up directive's isolated scope
      name: "@",          // name var passed by value (string, one-way)
      amount: "=",        // amount var passed by reference (two-way)
      save: "&"           // save action
    },
    template:             // replacement HTML (can use our scope vars here)
      "<div>" +
      "  {{name}}: <input ng-model='amount' />" +
      "  <button ng-click='save()'>Save</button>" +
      "</div>",
    replace: true,        // replace original markup with template
    transclude: false,    // do not copy original HTML content
    controller: [ "$scope", function ($scope) { …  }],
    link: function (scope, element, attrs, controller) {…}
 }
});   

从 javascript 字符串呈现 html 代码似乎很老套。 :D 我已经看到有 templateUrl 可以使用,但它会加载一整页,如果指令很小,这似乎远非最佳。

我想做的是加载一个包含大量命名模板的html文件。这很容易吗?如果没有,有人有成功的模式吗?

谁能指出我正确的方向?在代码和 html 分离了这么多年之后,我真的不想开始在我的代码中编写 html,我也不想通过扩展框架来开始我作为 AngularJS 开发人员的职业生涯。 ;)

还是我使用的指令有误? (上面的示例代码来自我阅读的一个教程)

【问题讨论】:

    标签: javascript html angularjs templates angularjs-directive


    【解决方案1】:

    是的,当然可以。您可以使用任何 html 页面创建 ng-template 脚本部分。请参阅我为可编辑指令http://jsfiddle.net/cmyworld/6gMXL/创建的这个小提琴@

    如果添加脚本如

    <script type="text/ng-template" id="editable-template"> </script>

    您可以使用 templateUrl 在指令定义中引用它们。

    【讨论】:

    • 谢谢,这确实为我指明了正确的方向。使用您的示例和
      我可以将模板放在一个单独的
    【解决方案2】:

    你已经猜对了大部分。

    不过,我不确定您所说的“整页”是什么意思。

    Angular 在模板“部分”上工作,就像服务器端模板可能...

    // currentDirective = {.....
    templateUrl : "/templates/current-directive.html"
    // ...}; return currentDirective;
    

    同时,该文件的内容只是:

    <div class="current-directive>
        <div><span>{{ property }}</span><button ng-click="method(arg)">click</button></div>
    </div>
    

    是的,这似乎是一种浪费。
    只需要几个 HTML 元素就可以完成整个往返过程。

    但是,Angular 也会缓存该指令模板。
    该指令的未来实例导致模板在内存中重建,使其比许多其他解决方案更轻(仅在实际使用时加载模板,并且只加载一次,而不是加载整个应用程序的模板价值,如果您只打算使用两页的小部件,或者一遍又一遍地访问服务器以重新生成模板)。

    也就是说,如果您确实有充分的理由将模板一起批处理,您可以做的是让您的服务器批处理所有模板化字符串 ''... 以及它们应该的所有 URL em> 以批处理方式存在于...中的对象数组中:

    /模板 我的模板.html 其他-template.html 另一个模板.html

    变成

    [{
        url : "/templates/my-template.html",
        template : '<div>{{prop}}</div>;
     } /*,...*/]
    

    然后,您可以做的是请求 $templateCache 对象。
    我不确定它到底是什么(服务/工厂),因此,我不确定它何时需要运行,但基本上,当一切都准备好时。

    如果该 JS 数组被动态打印到页面中,那么你可以说:

    angular.module("myApp").run(function ($templateCache) {
        templates.forEach(function (cached) {
            $templateCache.put(cached.url, cached.template);
        });
    });
    

    这发生在之前你实际上是在 Angular 内部(即:在 window.load 之前)。

    如果您要从 HTTP 请求中将该数组作为 JSON 包获取,那么您需要随后手动引导 Angular,因为自动使用 ng-app 为时已晚。

    angular.bootstrap(document.documentElement, ["myApp"]);
    

    另一种选择是在第一页上使用&lt;script&gt; 标签。

    <script type="text/ng-template" id="/templates/my-template.html">
        <div >{{ prop }}</div>
    </script>
    

    Angular 现在会自动将该模板缓存到该 URL。 您的所有模板现在都需要在脚本标签中,并嵌入到页面中,在 window.onload 事件之前,并且在 ng-app 边界的范围内。

    缺点是你现在又回到让用户下载所有东西,开始。

    为了使用这些预先缓存的模板,您需要做的就是将 $templateCache 注入指令(指令的顶级定义,而不是作用域/控制器很好),然后调用 @987654330 @

    // currentDirective = { ...
            template : $templateCache.get("/templates/current-directive.html"),
    // }; return directive
    

    无需扩展。
    请注意,使用“templateUrl”和使用$templateCache.get(url) 都有各自的缺点。

    【讨论】:

    • 为什么要在指令中使用template : $templateCache.get?如果它在缓存中,那么使用templateUrl 将在那里获取它。
    • 感谢您的回答,它帮助我理解了 angularjs。
    猜你喜欢
    • 2014-12-03
    • 1970-01-01
    • 2015-09-17
    • 2016-03-17
    • 2015-12-01
    • 1970-01-01
    • 2014-07-31
    • 2013-10-29
    相关资源
    最近更新 更多