如何在自定义指令中获取已计算的属性

2022-08-29 23:40:14

我正在尝试从我的自定义指令中获取已计算的属性,但我找不到正确的方法。

我创建了这个jsFiddle来详细说明。

<div ng-controller="MyCtrl">
    <input my-directive value="123">
    <input my-directive value="{{1+1}}">
</div>

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

我错过了什么?


答案 1

注意:当我找到更好的解决方案时,我会更新这个答案。我也保留旧的答案,以备将来参考,只要它们仍然相关。最新和最好的答案是第一位的。

更好的答案:

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

在创建指令时,angularjs 允许您创建一个隔离的作用域,其中包含一些与父作用域的绑定。这些绑定由您在 DOM 中附加元素的特性以及在指令定义对象中定义 scope 属性的方式指定。

您可以在 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";
});

断续器

<div ng-controller="myController">
    <div my-directive my-text="hello {{ bar }}" my-two-way-bind="foo" my-one-way-bind="bar">
    </div>
</div>

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

/* 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 .

“还行”回答:

由于这个答案被接受,但有一些问题,我将把它更新到一个更好的答案。显然,它是一种不位于当前范围属性中的服务,这意味着它只需要角度表达式,无法到达范围。,表达式是在angularjs启动时编译的,这意味着当我们尝试在指令方法中访问它们时,它们已经编译了。(已在指令中)。$parse{{}}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;
}​

.

<div ng-controller="MyCtrl">
    <input my-directive="123">
    <input my-directive="1+1">
    <input my-directive="'1+1'">
    <input my-directive="aaa">
</div>​​​​​​​​

这里应该注意的一件事是,如果要设置值字符串,则应将其括在引号中。(参见第三输入)

这是要玩的小提琴:http://jsfiddle.net/neuTA/6/

旧答案:

我不会为那些像我一样可能被误导的人删除它,请注意,使用$eval是正确的方法,但是$parse有不同的行为,你可能不需要在大多数情况下使用它。

这样做的方法是再次使用 .它不仅可以编译角度表达式,还可以访问当前作用域的属性。scope.$eval

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

在返回结果的当前作用域上执行表达式。表达式中的任何异常都将传播(未捕获)。这在计算角度表达式时很有用。


答案 2

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

<input my-directive value="{{1+1}}">

使用属性的方法:$observe

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

指令页面,

观察插值属性:用于观察包含插值的属性的值变化(例如 )。这不仅非常有效,而且也是轻松获得实际值的唯一方法,因为在链接阶段,插值尚未被评估,因此此时该值设置为 。$observesrc="{{bar}}"undefined

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

<input my-directive value="123">

如果值是数字或布尔值,并且需要正确的类型,则可以使用$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