javascript directives中文 - 如何獲取自定義指令中的評估屬性




directive教學 angularjs (6)

對於同樣的解決方案,我正在Angularjs directive with ng-Model尋找Angularjs directive with ng-Model
這是解決問題的代碼。

    myApp.directive('zipcodeformatter', function () {
    return {
        restrict: 'A', // only activate on element attribute
        require: '?ngModel', // get a hold of NgModelController
        link: function (scope, element, attrs, ngModel) {

            scope.$watch(attrs.ngModel, function (v) {
                if (v) {
                    console.log('value changed, new value is: ' + v + ' ' + v.length);
                    if (v.length > 5) {
                        var newzip = v.replace("-", '');
                        var str = newzip.substring(0, 5) + '-' + newzip.substring(5, newzip.length);
                        element.val(str);

                    } else {
                        element.val(v);
                    }

                }

            });

        }
    };
});


HTML DOM

<input maxlength="10" zipcodeformatter onkeypress="return isNumberKey(event)" placeholder="Zipcode" type="text" ng-readonly="!checked" name="zipcode" id="postal_code" class="form-control input-sm" ng-model="patient.shippingZipcode" required ng-required="true">


我的結果是:

92108-2223

我試圖從我的自定義指令中獲得一個評估屬性,但我找不到正確的方法。

我已經創建了這個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);
    }
});

我錯過了什麼?


對於需要在不使用隔離範圍的指令中進行插值的屬性值,例如,

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

directive頁面,

觀察插值屬性:使用$observe觀察包含插值的屬性的值更改(例如, src="{{bar}}" )。 這不僅非常高效,而且也是輕鬆獲取實際值的唯一方法,因為在鏈接階段插值尚未進行評估,因此此時將值設置為undefined

如果屬性值只是一個常數,例如,

<input my-directive value="123">

如果值是數字或布爾值,則可以使用http://docs.angularjs.org/api/ng.$rootScope.Scope#$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


var myApp = angular.module('myApp',[]);

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

    }
});

function MyCtrl($scope) {

}

使用$超時,因為在dom加載後指令調用,所以您的更改不適用


注意:我會更新這個答案,因為我找到更好的解決方案。 只要他們保持聯繫,我也會保留舊的答案供將來參考。 最新和最好的答案是第一位的。

更好的回答:

angularjs中的指令非常強大,但需要時間來理解哪些進程位於它們後面。

在創建指令時,angularjs允許您創建一個與父範圍綁定的獨立範圍。 這些綁定由您在DOM中附加元素的屬性以及如何在指令定義對像中定義範圍屬性來指定

有三種類型的綁定選項,您可以在範圍中定義,並將它們編寫為與前綴相關的屬性。

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

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

“還行”答案:

由於這個答案已被接受,但有一些問題,我將把它更新為更好的答案。 顯然, $parse是一個服務,它不在當前範圍的屬性中,這意味著它只需要角度表達式並且不能達到範圍。 {{}}表達式是在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;
}​

<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/ : 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

在返回結果的當前範圍內執行表達式。 表達式中的任何異常都會傳播(未捕獲)。 這在評估角度表達式時很有用。


很多好的答案在這裡,但有時候你只是想要一個簡單的,簡單的,舊的jQuery-ish解決方案。

我的解決方案不處理對DOM的更改。 如果屬性可能更改,請不要使用我的方法!

在我的情況下,我有一個元素,並需要檢索屬性(rel)的值。

模板:

<div ng-repeat="elm in array">
    <button class="poi-lines-show" rel="li-{{$index}}">button-text</button>
</div>

在我的指示中:

var buttons = element[0].querySelectorAll('button');
for (var i=0; i<buttons.length; i++) {
    var target = angular.element(buttons[i]);
    console.log(target.attr('rel')); // Outputs 'li-0', 'li-1', 'li-2' etc 
}

如果您的DIV標記後面緊跟IMG標記,您還可以使用:

$(this).next();




javascript binding angularjs directive