カスタムディレクティブから evaluate 属性を取得しようとしていますが、正しい方法が見つかりません。
私は この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);
}
});
何が足りないの?
Notice:より良い解決策が見つかると、この回答を更新します。私はまた、それらが関連している限り、将来の参考のために古い答えを保管します。最新かつ最善の答えが最初に来る。
Angularjsの指令は非常に強力ですが、どのプロセスがそれらの背後にあるのかを理解するのに時間がかかります。
ディレクティブを作成している間、angularjsはあなたがisolated scopeを親のscopeへのいくつかの束縛で作成することを可能にします。これらのバインディングは、DOMで要素を付加する attribute と、ディレクティブ定義オブジェクトで 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
<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>
ここで気を付けなければならないことは、値の文字列を設定したい場合は、それを引用符で囲む必要があるということです。 (3番目の入力を参照)
ここで遊ぶためのフィドルです: 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
現在のスコープで式を実行して結果を返します。式の中の例外はすべて伝播されます(キャッチされません)。これは角度表現を評価するときに便利です。
分離スコープを使用していないディレクティブで補間する必要がある属性値の場合
<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);
})
}
});
ディレクティブ pageから、
内挿された属性を観察する:内挿を含む属性の値の変化を観察するには
$observe
を使用します(例:src="{{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
を使います。
私は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
ここでの他の答えは非常に正確で価値があります。しかし、時にはあなたは単純なことを望みます:更新を必要とせずに、そして分離スコープをめちゃくちゃにせずに、ディレクティブのインスタンス生成時に単純で古い解析値を取得します。たとえば、宣言ペイロードをディレクティブに配列またはハッシュオブジェクトとして次の形式で指定すると便利です。
my-directive-name="['string1', 'string2']"
その場合は、追いついてニースの基本的なangular.$eval(attr.attrName)
を使うことができます。
element.val("value = "+angular.$eval(attr.value));
Working Fiddle 。
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のロード後にディレクティブを呼び出して変更が適用されないため、$ timeoutを使用します。