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

时间:2014-01-22 04:02:12

标签: javascript angularjs angularjs-directive angularjs-scope

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

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

<error-message name="paymentPlanForm.position" error="required">
    This field is required.
</error-message>

这会产生以下结果:

<p ng-show="paymentPlanForm.position.$dirty && paymentPlanForm.position.$error.required">
    <span class="fontawesome-remove"></span> This field is required.
</p>

我开始编写一个指令来完成此操作,如下所示:

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;
        }
    }
});

模板如下:

<p ng-show="{{name}}.$dirty && {{name}}.$error.{{error}}">
    <span class="fontawesome-remove"></span>
    <span ng-transclude></span>
</p>

我认为这样可行,但是当试图在模板中解析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

当我检查Firebug中的元素时,动态值已成功传递,但我猜范围有问题,或其他。

我怎样才能有角度去做我想做的事?

1 个答案:

答案 0 :(得分:5)

问题是您的链接函数在Angular编译模板后运行。因此nameerror在编译期间没有设置ngShow检查其属性(因此它看到的是“。”而前面没有任何内容的错误)。

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

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

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

scope:{
        name: '@',
        error: '@'
     },

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

template: '<div><p ng-show="$parent.{{name}}.$dirty">Dirty</p><p ng-show="$parent.{{name}}.$error.{{error}}"><span ng-transclude></span></p></div>',

注意我调整了你的模板,将脏的和所需的测试分开,以便更容易看到它的工作。

这是a working fiddle