programing

AngularJS의 커스텀 디렉티브 *sure scope* 내에서 부모 스코프에 액세스하려면 어떻게 해야 합니까?

newstyles 2023. 2. 28. 23:20

AngularJS의 커스텀 디렉티브 *sure scope* 내에서 부모 스코프에 액세스하려면 어떻게 해야 합니까?

지시문 내에서 "부모" 범위에 액세스할 수 있는 방법을 찾고 있습니다.위로부터의 범위, 트랜스루드, 요구, 변수(또는 범위 자체)의 임의의 조합.저는 전적으로 기꺼이 몸을 뒤로 젖히지만, 완전히 진부하거나 유지 불가능한 것은 피하고 싶습니다.들어 지금 할 수 은 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 예.$scopepreLink 매개 변수를 하여 preLink 매개 변수를 합니다.$sibling'아주'하다

가 정말 은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.$watch상위 스코프의 식내가 할 수 있다면, 여기서 내가 하려는 것을 이룰 수 있을 야: 각진.JS - 변수가 있는 부분 렌더링 방법

중요한 점은 디렉티브는 같은 부모 범위 내에서 재사용할 수 있어야 한다는 것입니다.따라서 기본 동작(범위: false)은 작동하지 않습니다.지시의 인스턴스당 개별 스코프가 필요합니다.그리고 나서$watch상위 스코프에 존재하는 변수입니다.

코드 샘플은 1000 워드의 가치가 있습니다.따라서 다음과 같습니다.

app.directive('watchingMyParentScope', function() {
    return {
        require: /* ? */,
        scope: /* ? */,
        transclude: /* ? */,
        controller: /* ? */,
        compile: function(el,attr,trans) {
            // Can I get the $parent from the transclusion function somehow?
            return {
                pre: function($s, $e, $a, parentControl) {
                    // Can I get the $parent from the parent controller?
                    // By setting this.$scope = $scope from within that controller?

                    // Can I get the $parent from the current $scope?

                    // Can I pass the $parent scope in as an attribute and define
                    // it as part of this directive's scope definition?

                    // What don't I understand about how directives work and
                    // how their scope is related to their parent?
                },
                post: function($s, $e, $a, parentControl) {
                    // Has my situation improved by the time the postLink is called?
                }
            }
        }
    };
});

자세한 내용은 AngularJS에서 스코프 프로토타입/프로토타입 상속의 차이점을 참조하십시오.

( 「」: 「」).$parent

  1. 디폴트)scope: false - 스코프를 하지 않기 .)- 「상속되지 않습니다.지시문의 범위는 상위/컨테이너와 동일합니다.에서는 첫 파라미터으로 '''는 ''')를 합니다.scope를 참조해 주세요.

  2. scope: true으로 상속되는 를 만듭니다. - 부모 스코프로부터 상속됩니다.되어 있는 은, 「Directive」에서 할 수 .scope(숨기거나 속성에 .기본 스코프 속성에 쓰는 것에 주의해 주세요.이 경우 디렉티브스코프에 새로운 속성이 생성됩니다(같은 이름의 부모 스코프 속성을 숨기거나 섀도우 합니다).

  3. scope: { ... }는 새로운 를 만듭니다. - 격리/경계 범위를 만듭니다.시제품적으로 상위 범위를 상속하지 않습니다. 할 수 .$parent아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.가 사용되고 있는 디렉티브에 한 부모 을할 필요가 .=,@ , , , , 입니다.&표기법

  4. transclude: true 범위를 . - 합니다. - "제외된" 하위 범위를 .디렉티브에 의해서 격리 스코프도 작성되는 경우, 트랜스코프된 스코프와 격리 스코프는 형제입니다.$parent각 범위의 속성이 동일한 상위 범위를 참조합니다.
    각도 v1.3 업데이트:지시문이 분리 범위도 생성하는 경우 변환된 범위는 분리 범위의 하위 항목이 됩니다.트랜스코프된 스코프와 격리된 스코프는 더 이상 형제 스코프가 아닙니다.$parent변환된 스코프의 속성은 격리 스코프를 참조합니다.

위 링크에는 4가지 유형의 예시와 그림이 있습니다.

지시어의 컴파일 함수(여기서 설명한 바와 같이 https://github.com/angular/angular.js/wiki/Dev-Guide:-Understanding-Directives))에서는 스코프에 액세스할 수 없습니다.링크 기능에서 디렉티브의 스코프에 액세스 할 수 있습니다.

감시:

위의 1. 및 2.의 경우: 보통 속성을 통해 디렉티브에 필요한 부모 속성을 지정하고 $watch it:

<div my-dir attr1="prop1"></div>
scope.$watch(attrs.attr1, function() { ... });

오브젝트 속성을 감시하는 경우 $parse를 사용해야 합니다.

<div my-dir attr2="obj.prop2"></div>
var model = $parse(attrs.attr2);
scope.$watch(model, function() { ... });

3. (scope)의 경우는, 3 을 을 확인해 .@ ★★★★★★★★★★★★★★★★★」=★★★★★★★★★★★★★★★★★★:

<div my-dir attr3="{{prop3}}" attr4="obj.prop4"></div>
scope: {
  localName3: '@attr3',
  attr4:      '='  // here, using the same name as the attribute
},
link: function(scope, element, attrs) {
   scope.$watch('localName3', function() { ... });
   scope.$watch('attr4',      function() { ... });

컨트롤러 메서드에 액세스한다는 것은 디렉티브 컨트롤러/링크/스코프에서 부모 스코프상의 메서드에 액세스 하는 것을 의미합니다.

디렉티브가 부모 스코프를 공유/상속하고 있는 경우는 부모 스코프 메서드를 호출하는 것만으로 간단합니다.

격리된 지시어 범위에서 부모 스코프 메서드에 액세스하려는 경우 작업이 거의 필요하지 않습니다.

독립 다이렉트 스코프에서 부모 스코프 메서드를 호출하거나 부모 스코프 변수(옵션 #6)를 감시하는 옵션은 거의 없습니다.

사용한 것에 주의:link function쓸 수 요.directive controller요구 사항을 기반으로 합니다.

옵션 #1. 오브젝트 리터럴 경유 및 디렉티브html 템플릿 경유

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChanged({selectedItems:selectedItems})" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html"
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnedFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]

});

작업 plnkr:http://plnkr.co/edit/rgKUsYGDo9O3tewL6xgr?p=preview

옵션 #2.오브젝트 리터럴 경유 및 디렉티브링크/스코프 경유

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
 ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html",
    link: function (scope, element, attrs){
      scope.selectedItemsChangedDir = function(){
        scope.selectedItemsChanged({selectedItems:scope.selectedItems});  
      }
    }
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnedFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]
});

작업 plnkr:http://plnkr.co/edit/BRvYm2SpSpBK9uxNIcTa?p=preview

옵션 #3.Function 참조를 통해 지시 HTML 템플릿에서

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
 ng-change="selectedItemsChanged()(selectedItems)" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems:'=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html"
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]
});

작업 plnkr:http://plnkr.co/edit/Jo6FcYfVXCCg3vH42BIz?p=preview

옵션 #4.Function reference 경유 및 directive link/scope 경유

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html",
    link: function (scope, element, attrs){
      scope.selectedItemsChangedDir = function(){
        scope.selectedItemsChanged()(scope.selectedItems);  
      }
    }
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnedFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]

});

작업 plnkr:http://plnkr.co/edit/BSqx2J1yCY86IJwAnQF1?p=preview

옵션 5: ng-model양방향 바인딩을 통해 부모 스코프 변수를 업데이트할 수 있습니다.따라서 경우에 따라서는 부모 스코프 함수를 호출할 필요가 없습니다.

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter ng-model="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
 ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=ngModel'
    },
    templateUrl: "itemfilterTemplate.html"
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]
});

작업 plnkr:http://plnkr.co/edit/hNui3xgzdTnfcdzljihY?p=preview

옵션 6: Through 및 이것은 두 가지 방법으로 결합됩니다.items위의 모든 예에서 항목이 상위 범위에서 수정되는 경우 지침의 항목도 변경사항을 반영할 것이다.

스코프에서 를 하여 할 수 .$watch ★★★★★★★★★★★★★★★★★」$watchCollection와 같이

html

<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <p>Hello {{user}}!</p>
  <p>directive is watching name and current item</p>
  <table>
    <tr>
      <td>Id:</td>
      <td>
        <input type="text" ng-model="id" />
      </td>
    </tr>
    <tr>
      <td>Name:</td>
      <td>
        <input type="text" ng-model="name" />
      </td>
    </tr>
    <tr>
      <td>Model:</td>
      <td>
        <input type="text" ng-model="model" />
      </td>
    </tr>
  </table>

  <button style="margin-left:50px" type="buttun" ng-click="addItem()">Add Item</button>

  <p>Directive Contents</p>
  <sd-items-filter ng-model="selectedItems" current-item="currentItem" name="{{name}}" selected-items-changed="selectedItemsChanged" items="items"></sd-items-filter>

  <P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}}</p>
</body>

</html>

스크립트 app.display

var app = angular.snarplunker', [];

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      name: '@',
      currentItem: '=',
      items: '=',
      selectedItems: '=ngModel'
    },
    template: '<select ng-model="selectedItems" multiple="multiple" style="height: 140px; width: 250px;"' +
      'ng-options="item.id as item.name group by item.model for item in items | orderBy:\'name\'">' +
      '<option>--</option> </select>',
    link: function(scope, element, attrs) {
      scope.$watchCollection('currentItem', function() {
        console.log(JSON.stringify(scope.currentItem));
      });
      scope.$watch('name', function() {
        console.log(JSON.stringify(scope.name));
      });
    }
  }
})

 app.controller('MainCtrl', function($scope) {
  $scope.user = 'World';

  $scope.addItem = function() {
    $scope.items.push({
      id: $scope.id,
      name: $scope.name,
      model: $scope.model
    });
    $scope.currentItem = {};
    $scope.currentItem.id = $scope.id;
    $scope.currentItem.name = $scope.name;
    $scope.currentItem.model = $scope.model;
  }

  $scope.selectedItems = ["allItems"];

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
  }]
});

지침에 대한 자세한 설명은 언제든지 AngularJs 설명서를 참조하십시오.

 scope: false
 transclude: false

같은 범위(부모 요소 포함)를 갖게 됩니다.

$scope.$watch(...

이 두 가지 옵션 범위와 트랜스코드에 따라 부모 범위에 액세스하는 방법은 여러 가지가 있습니다.

여기 제가 사용한 요령이 있습니다. 부모 스코프를 유지하여 원하는 디렉티브 이외의 장소에 배치하는 "더미" 디렉티브를 만듭니다.예를 들어 다음과 같습니다.

module.directive('myDirectiveContainer', function () {
    return {
        controller: function ($scope) {
            this.scope = $scope;
        }
    };
});

module.directive('myDirective', function () {
    return {
        require: '^myDirectiveContainer',
        link: function (scope, element, attrs, containerController) {
            // use containerController.scope here...
        }
    };
});

그리고 나서.

<div my-directive-container="">
    <div my-directive="">
    </div>
</div>

가장 우아한 해결책은 아닐지 몰라도, 일은 잘 해결됐어.

ES6 클래스 및 구문을 사용하는 경우 약간 다른 작업을 수행해야 합니다.

하고, 이 토픽에 해 주세요.vm는 는 입니다.ControllerAs 의 값

myApp.directive('name', function() {
  return {
    // no scope definition
    link : function(scope, element, attrs, ngModel) {

        scope.vm.func(...)

모든 것을 시도해 본 끝에 마침내 해결책을 생각해 냈다.

템플릿에 다음 항목을 배치하기만 하면 됩니다.

{{currentDirective.attr = parentDirective.attr; ''}}

현재 범위에 액세스할 상위 범위 속성/변수만 씁니다.

, 「」에 해 주세요.; ''각도만 출력합니다(Angular에서는 모든 스테이트먼트를 평가하지만 마지막 스테이트먼트를 평가합니다.

좀 허술하긴 하지만 몇 시간 동안 시행착오를 거듭한 끝에 제 역할을 할 수 있습니다.

언급URL : https://stackoverflow.com/questions/17900201/how-to-access-parent-scope-from-within-a-custom-directive-with-own-scope-in-an