【问题标题】:Angular JS Directive loaded in expressionAngular JS 指令在表达式中加载
【发布时间】:2016-09-16 07:24:12
【问题描述】:

我是 Angular 的新手,已经找到了大量关于指令和嵌套的资源,但似乎无法让这个简单的示例工作。所以基本上我正在处理一个标签集,我有一个 HTML 模板:

tabset.html

<div>
    <ul>
        <li ng-repeat="tab in tabset.tabs" ng-class="{active:tabset.current()==$index}">
            <a href ng-click="tabset.current($index)">{{tab}}</a>
        </li>
    </ul>
    <div>
        <div ng-repeat="pane in tabset.panes">
            <div ng-show="tabset.current()==$index">
                {{pane.contents}}
            </div>
        </div>
    </div>
</div>

还有一个搜索表单模板:

search-form.html

<div>
    <form name="ytSearch" ng-submit="YTCtrl.submit()" novalidate>
        <label for="search_box">Search For: </label>
        <input id="search_box" ng-model="YTCtrl.searchString"/>
        <br>
        <label for="location">Location: </label>
        <input id="location" ng-model="YTCtrl.location"/>
        within
        <input type="numeric" value="100" ng-model="YTCtrl.locationRadius" />
        <select ng-model="YTCtrl.locationUnit">
            <option value="ft">Feet</option>
            <option value="m">Meters</option>
            <option value="mi">Miles</option>
            <option value="km">Kilometers</option>
        </select>
        <br>
        <label for="search_order">Sort By: </label>
        <select id="search_order" ng-model="YTCtrl.order">
            <option value="relevance">Relevance</option>
            <option value="date">Date</option>
            <option value="rating">Rating</option>
        </select>
        <br>
        <button id="search">
            Search
        </button>
    </form>
</div>

还有一个简单的应用文件,其中包含 2 个指令来处理每个模板:

app.js

(function() {
    angular.module("JHYT", [])
        .directive("sidebarTabset", function($compile) {
            return {
                restrict : 'E',
                templateUrl : 'tabset.html',
                controller : function($scope, $compile, $http) {
                    this._current = 0;
                    this.current = function(i) {
                        if (i != null)
                            this._current = i;
                        return this._current;
                    };
                    this.tabs = ['Search', 'Favorite'];
                    this.panes = [{
                        contents : "<search-form></search-form>"
                    }, {
                        contents : "Favorite Pane"
                    }];
                },
                controllerAs : 'tabset',
            };
        }).
        directive("searchForm", function() {
            return {
                restrict : 'E',
                templateUrl : 'search-form.html',
                controller : function($scope, $compile, $http) {
                    this.searchString = '';
                    this.location = '';
                    this.locationRadius = '';
                    this.locationUnit = 'mi';
                    this.order = 'relevance';
                    this.submit = function() {
                        console.log("Submit");
                    };
                },
                controllerAs : 'YTCtrl',
            }
        });
})();

所以你可能会说,这个想法是能够将 JSON 对象发送到选项卡集(可能通过服务)并让它构建一个动态选项卡集,它实际上完全按照我的预期工作。不工作的是,在第一个选项卡中,&lt;search-form&gt;&lt;/search-form&gt; 的内容没有被处理,并且标签在内容区域中呈现为纯文本。

由于这是一个选项卡集,“子”不需要来自“父”的任何内容,搜索表单和选项卡本身没有范围依赖性。在看到一些嵌套结构的示例后,我尝试使用链接和编译函数,但似乎无法让它们工作。

如何处理该变量的内容,以便使用其模板呈现元素指令?

编辑:

@sielakos 给了我我所希望的,一种可重复使用的方法。

我在我的模块中添加了一个名为 compile 的指令,它添加了一个包装器以允许我使用纯文本:

.directive("compile", function($compile){
            return {
                restrict: 'A',
                link: function(scope, element, attr){
                    attr.$observe("compile", function(str){
                        var compiled = $compile("<div>"+str+"</div>")(scope);
                        jQuery(element).replaceWith(compiled);
                    })
                }
            }
        })

我改变了我的标签集以使用这个指令:

<div>
    <ul>
        <li ng-repeat="tab in tabset.tabs" ng-class="{active:tabset.current()==$index}">
            <a href ng-click="tabset.current($index)">{{tab}}</a>
        </li>
    </ul>
    <div>
        <div ng-repeat="pane in tabset.panes">
            <div ng-show="tabset.current()==$index">
                <div compile="{{pane.contents}}"></div>
            </div>
        </div>
    </div>
</div>

【问题讨论】:

  • 您的 html 标记中的“sidebar-tabset”元素在哪里?
  • 我认为这是因为在 sidebarTabset 你使用 this.panes = [{ contents : "" }, { contents : "Favorite Pane" }];在控制器中..尝试将其放入预链接功能中
  • @ChrisHermut 我提供的代码只是指令和模板。 “sidebar-tabset”元素在 index.html 中,正如我所说,它按预期工作。
  • @MayK 我不熟悉预链接功能,但是根据我阅读的其他示例,由于 ng-repeat,我找不到使用链接功能来完成此操作的方法在标签集中
  • 先放到scope.panes中只是为了测试问题是否真的来自这里

标签: angularjs angular2-directives


【解决方案1】:

如果您希望像使用模板一样使用它,则需要使用$compile 服务编译您的字符串。否则将被视为普通字符串并按原样显示。

这里是如何在指令中使用它的示例:

var compiled = $compile(str)(scope);
element.empty();
element.append(compiled); 

如果您愿意,可以查看这个小提琴以获得更复杂的示例: https://jsfiddle.net/x78uuwp2/

在这里,我创建了简单的编译指令,它将字符串编译并作为元素体放入当前范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 2015-08-17
    • 2015-09-07
    • 1970-01-01
    相关资源
    最近更新 更多