如何在指令模板中使用动态ng-show值?

ege*_*ari 5 javascript angularjs angularjs-directive angularjs-scope

我正在学习角度,我正在尝试通过使用angular指令来减少执行一些常见操作所需的代码,例如显示错误消息.

我想创建的一个指令是这样的:

<error-message name="paymentPlanForm.position" error="required">
    This field is required.
</error-message>
Run Code Online (Sandbox Code Playgroud)

这将产生以下结果:

<p ng-show="paymentPlanForm.position.$dirty && paymentPlanForm.position.$error.required">
    <span class="fontawesome-remove"></span> This field is required.
</p>
Run Code Online (Sandbox Code Playgroud)

我开始写一个指令来完成这个,如下所示:

app.directive("errorMessage", function() {
    return {
        restrict: 'E',
        transclude: true,
        replace: true,
        templateUrl: 'views/partials/errorMessage.html',
        link: function(scope, element, attributes) {
            scope.name = attributes.name;
            scope.error = attributes.error;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

模板如下:

<p ng-show="{{name}}.$dirty && {{name}}.$error.{{error}}">
    <span class="fontawesome-remove"></span>
    <span ng-transclude></span>
</p>
Run Code Online (Sandbox Code Playgroud)

我认为这会有效,但是当试图ng-show在模板内部解析时,Angular似乎崩溃了:

Error: [$parse:syntax] Syntax Error: Token '.' not a primary expression at column 1 of the expression [.$dirty && .$error.] starting at [.$dirty && .$error.].
http://errors.angularjs.org/1.2.9/$parse/syntax?p0=.&p1=not%20a%20primary%20expression&p2=1&p3=.%24dirty%20%26%26%20.%24error.&p4=.%24dirty%20%26%26%20.%24error.
minErr/<@http://localhost:8080/keiko/vendor/js/angular.js:78
Run Code Online (Sandbox Code Playgroud)

当我在Firebug中检查元素时,动态值已成功传递,但我猜这个范围有问题,或者别的什么.

我怎么能有角度去做我想要的?

Kay*_*ave 5

问题是你的链接函数在Angular编译模板后运行.因此name,error在编译期间没有设置时ngShow检查其属性(因此它看到的是"."而前面没有任何内容的错误).

ngShow只在编译时查看其属性,然后它会监视在该点传递的任何表达式.所以它永远不会看到链接功能改变其属性.

html在您查看时已经更新,这使得它更加令人困惑.

我的建议是使用隔离范围并以这种方式传递这两个属性.这将解决时间问题,而且无论如何都要将隔离范围用于此类指令并不是一个坏主意:

scope:{
        name: '@',
        error: '@'
     },
Run Code Online (Sandbox Code Playgroud)

现在表格数据将在指令的父级范围内进行权衡,因此我们需要$parent在模板中添加引用:

template: '<div><p ng-show="$parent.{{name}}.$dirty">Dirty</p><p ng-show="$parent.{{name}}.$error.{{error}}"><span ng-transclude></span></p></div>',
Run Code Online (Sandbox Code Playgroud)

注意我调整了您的模板以分隔脏和所需的测试,以便更容易看到它的工作.

这是一个工作小提琴