如何在自定义指令中获取已评估的属性

13 浏览
0 Comments

如何在自定义指令中获取已评估的属性

我正试图从我的自定义指令中获得一个计算过的属性,但我找不到正确的方法。

我创建了这个jsFiddle来说明。

    
    
myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
        element.val("value = "+attr.value);
    }
});

我缺少了什么?

admin 更改状态以发布 2023年5月24日
0
0 Comments

对于需要在未使用隔离作用域的指令中进行插值的属性值,例如


使用属性方法$observe

myApp.directive('myDirective', function () {
  return function (scope, element, attr) {
    attr.$observe('value', function(actual_value) {
      element.val("value = "+ actual_value);
    })
 }
});

来自指令页面,

观察插值属性:使用$observe观察包含插值的属性的值更改(例如src="{{bar}}")。这不仅非常有效,而且也是唯一轻松获取实际值的方法,因为在链接阶段期间尚未评估插值,因此在此时的值设置为undefined

如果属性值只是一个常量,例如


则如果该值为数字或布尔值,并且您希望获取正确的类型,则可以使用$eval

return function (scope, element, attr) {
   var number = scope.$eval(attr.value);
   console.log(number, number + 1);
});

如果属性值是字符串常量,或者您希望在指令中使用字符串类型的值,则可以直接访问它:

return function (scope, element, attr) {
   var str = attr.value;
   console.log(str, str + " more");
});

然而,在您的情况下,由于您希望支持插值值和常量,请使用$observe

0
0 Comments

注意:当我找到更好的解决方案时,我会更新这个答案。只要这些解决方案仍然相关,我也会保留旧的答案以备将来参考。最新和最好的答案排在前面。

更好的答案:

在AngularJS中,指令非常强大,但需要时间来理解它们背后的过程。

创建指令时,AngularJS允许您创建一个带有一些绑定到父级作用域的隔离作用域。这些绑定由您在DOM中附加元素的属性以及在指令定义对象中定义scope属性的方式来指定。

您可以在作用域中定义3种绑定选项,将这些选项作为相关属性的前缀写入。

angular.module("myApp", []).directive("myDirective", function () {
    return {
        restrict: "A",
        scope: {
            text: "@myText",
            twoWayBind: "=myTwoWayBind",
            oneWayBind: "&myOneWayBind"
        }
    };
}).controller("myController", function ($scope) {
    $scope.foo = {name: "Umur"};
    $scope.bar = "qwe";
});

HTML


在这种情况下,在指令的作用域内(无论它是在链接函数还是控制器中),我们可以像这样访问这些属性:

/* Directive scope */
in: $scope.text
out: "hello qwe"
// this would automatically update the changes of value in digest
// this is always string as dom attributes values are always strings
in: $scope.twoWayBind
out: {name:"Umur"}
// this would automatically update the changes of value in digest
// changes in this will be reflected in parent scope
// in directive's scope
in: $scope.twoWayBind.name = "John"
//in parent scope
in: $scope.foo.name
out: "John"
in: $scope.oneWayBind() // notice the function call, this binding is read only
out: "qwe"
// any changes here will not reflect in parent, as this only a getter .

"还行"的答案:

由于这个答案被接受了,但存在一些问题,我要更新它到更好的答案。显然,$parse是一个不位于当前作用域属性中的服务,这意味着它只接受Angular表达式,而无法访问作用域。
{{,}}表达式在AngularJS初始化时被编译,这意味着当我们在指令的postlink方法中尝试访问它们时,它们已经被编译。({{1+1}}在指令中已经是2)。

这就是您想要使用的方式:

var myApp = angular.module('myApp',[]);
myApp.directive('myDirective', function ($parse) {
    return function (scope, element, attr) {
        element.val("value=" + $parse(attr.myDirective)(scope));
    };
});
function MyCtrl($scope) {
    $scope.aaa = 3432;
}​

    
    
    
    
​​​​​​​​

这里有一件事需要注意的是,如果你想设置字符串值,你应该用引号包裹它。(参见第三个输入)

这里是一个可以操作的示例:http://jsfiddle.net/neuTA/6/

旧回答:

我不会移除这个回答,因为像我这样容易被误导的人需要注意,使用$eval是完全正确的方法,但是$parse的行为不同,您可能不需要在大多数情况下使用它。

做法还是一样,使用scope.$eval。它不仅编译了Angular表达式,还可以访问当前作用域的属性。

var myApp = angular.module('myApp',[]);
myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
        element.val("value = "+ scope.$eval(attr.value));
    }
});
function MyCtrl($scope) {
}​

你缺失的是$eval

http://docs.angularjs.org/api/ng.$rootScope.Scope#$eval

在当前作用域上执行表达式并返回结果。表达式中的任何异常会传播(未捕获)。这在评估Angular表达式时很有用。

0