如何在指令范围内设置值

时间:2014-03-27 11:45:22

标签: javascript angularjs angularjs-directive

我有多个几乎相同的AngularJS指令 - 只有两个不同之处:模板URL和链接函数中的一个单独元素。对于每个指令,两者都是常量。因此,为简单起见,这就是它的样子:

app.directive("myDirective", [function() {
    return {
        templateUrl: "this/path/changes.html",
        scope: true,
        link: function(scope, element, attrs) {
            var veryImportantString = "this_string_changes";
            // a few dozen lines of code identical to all directives
        }
    };
}]);

现在,将链接功能移动到常用位置是显而易见的。对我来说不那么明显的是如何在范围内设置“非常重要的字符串”(或以其他方式将其传递给指令)而不在HTML中声明它。

这是我尝试过的。

app.directive("myDirective", [function() {
    return {
        templateUrl: "this/path/changes.html",
        scope: {
            veryImportantString: "this_string_changes"
        },
        link: someCommonFunction
    };
}]);

不,显然范围配置不接受来自任何人的值。我可以绑定来自HTML属性的值,但这正是我不想做的。

还试过这个:

app.directive("myDirective", [function() {
    return {
        templateUrl: "this/path/changes.html",
        veryImportantString: "this_string_changes",
        scope: true,
        link: function(scope, element, attrs) {
            var veryImportantString = this.veryImportantString;
        }
    };
}]);

但是,唉,然后调用链接函数,将this设置为其他内容。

我认为这可行:

app.directive("myDirective", [function() {
    return {
        templateUrl: "this/path/changes.html",
        scope: true,
        compile: function(element, attrs) {
            // no access to the scope...
            attrs.veryImportantString = "this_string_changes";
            return someCommonFunction;
        }
    };
}]);

然而,我并非100%确定这也是我想要的,因为它是一个肮脏的解决方法。

我的其他选择是什么?

2 个答案:

答案 0 :(得分:2)

我设计了一种完全不同的方法:使用类似工厂的函数来生成指令。

var factory = function(name, template, importantString) {
    app.directive(name, [function() {
        return {
            scope: true,
            templateUrl: template,
            link: function(scope, element, attrs) {
                var veryImportantString = importantString;
                // directive logic...
            }
        };
    }]);
};

然后,为了创建单独的指令,我只需调用:

factory("myDirective", "/path/to/template.html", "important");
factory("myDirective2", "/path/to/template2.html", "important2");

答案 1 :(得分:1)

以下内容如何:

在您定义someCommonFunction的任何地方之前,请添加

var veryImportantString = "someOptionalDefault"

然后将veryImportantString放在someCommonFunction.directive()

的范围内

然后您可以将指令代码更改为:

app.directive("myDirective", [function() {
    return {
        templateUrl: "this/path/changes.html",
        scope: true,
        link: function(args){
          veryImportantString = "thatUberImportantValue";
          someCommonFunction(args);
        }
    };
}]);

Proof of concept fiddle