Angular: Selectively compile templates

时间:2015-07-13 20:59:30

标签: javascript angularjs templates

I know that ng-non-bindable allows a given element and its children to be not compiled as a template. It seems it was designed to be peppered throughout a template as needed. Is there a way to tell Angular to not process a given element, BUT to "poke holes" into that and allow selected child elements to be processed? For example, I'd love to be able to do something like this:

<div ng-non-bindable>
    <div>{{2+2}}</div>
    <div ng-bindable>{{2+2}}</div>
</div>

And have it output:

{{2+2}}

4

I understand that ng-non-bindable wouldn't even allow ng-bindable to be processed, even if it existed. But does anything exist to allow an approach to templates like I've expressed?

To be more thorough, my ideal solution would not process anything Angular until if found the ng-bindable, not just the curly brace expressions. For example:

<div ng-non-bindable>
    <div ng-repeat="n in [1,2,3]">{{n+2}}</div>
    <div ng-bindable ng-repeat="n in [1,2,3]">{{n+2}}</div>
</div>

would result in:

{{n+2}}

3

4

5

1 个答案:

答案 0 :(得分:4)

自定义nonBindable指令

由于配置了指令,你将无法使用ngNonBindable(好吧,你可以装饰它)。但是,使用此行为编写自定义指令非常容易:

app.directive('nonBindable', function($compile) {
    return {
        terminal: true, 
        priority: 999,
        compile: function(tElement) {
            return function(scope) {
                var bindable = tElement[0].querySelectorAll('[bindable]');
                [].forEach.call(bindable, function(el) {
                    $compile(el)(scope);
                });    
            };
        }
    };
});

并像这样使用它:

<div non-bindable>
    <div>{{2+2}}</div>
    <div bindable>{{2+2}}</div>
</div>

<br><br>

<div non-bindable>
    <div ng-repeat="n in [1,2,3]">{{n+2}}</div>
    <div bindable ng-repeat="n in [1,2,3]">{{n+2}}</div>
</div>

演示: http://plnkr.co/edit/NEDP4WkBN4TlXdXKo8WI?p=preview

装饰ngNonBindable

您可以像这样装饰原始ngNonBindable指令:

app.config(function($provide) {
    $provide.decorator('ngNonBindableDirective', function($delegate, $compile) {
        var directive = $delegate[0];
        directive.compile = function(tElement) {
            return function(scope) {
                var bindable = tElement[0].querySelectorAll('[bindable]');
                [].forEach.call(bindable, function(el) {
                    $compile(el)(scope);
                });
            };
        };
        return $delegate;
    });
});

并以这种方式使用它:

<div ng-non-bindable>
    <div>{{2+2}}</div>
    <div bindable>{{2+2}}</div>
</div>

<br><br>

<div ng-non-bindable>
    <div ng-repeat="n in [1,2,3]">{{n+2}}</div>
    <div bindable ng-repeat="n in [1,2,3]">{{n+2}}</div>
</div>

演示: http://plnkr.co/edit/HVczVkkQR88hC7191ep0?p=preview