[javascript] 사용자 지정 지시문 내에서 평가 된 특성을 얻는 방법

사용자 지정 지시문에서 평가 된 속성 을 얻으려고하는데 올바른 방법을 찾을 수 없습니다.

정교한 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);
    }
});

내가 무엇을 놓치고 있습니까?



답변

참고 : 더 나은 솔루션을 찾으면이 답변을 업데이트합니다. 또한 관련이 유지되는 한 나중에 참조 할 수 있도록 이전 답변을 유지합니다. 최신의 최고의 답변이 우선입니다.

더 나은 답변 :

angularjs의 지시문은 매우 강력하지만 어떤 프로세스가 뒤에 있는지 이해하는 데 시간이 걸립니다.

지시문을 작성하는 동안 angularjs를 사용하면 상위 범위에 대한 바인딩으로 격리 된 범위 를 작성할 수 있습니다 . 이러한 바인딩은 DOM에서 요소를 연결 하는 속성지시문 정의 객체 에서 범위 속성 을 정의하는 방법으로 지정됩니다 .

범위에서 정의 할 수있는 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 .

“여전히 OK”답변 :

이 답변은 받아 들였지만 몇 가지 문제가 있으므로 더 나은 답변으로 업데이트하겠습니다. 분명히 $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);
    })
 }
});

로부터 지시 페이지,

보간 된 속성 관찰 : 보간 $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.


답변

다른 답변은 매우 정확하고 귀중합니다. 그러나 때로는 업데이트가 필요하지 않고 격리 범위를 망칠 필요없이 지시문 인스턴스화에서 일반 오래된 구문 분석 값을 얻는 것이 간단합니다. 예를 들어, 지시문에 선언적 페이로드를 배열 또는 해시 객체로 형식으로 제공하는 것이 편리 할 수 ​​있습니다.

my-directive-name="['string1', 'string2']"

이 경우 추적을 자르고 멋진 기본을 사용할 수 있습니다 angular.$eval(attr.attrName).

element.val("value = "+angular.$eval(attr.value));

바이올린 .


답변

같은 솔루션을 찾고있었습니다 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


답변

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 사용


답변