AngularJS доступ к родительской области от дочернего контроллера
Я установил свои контроллеры с помощью data-ng-controller="xyzController as vm"
У меня есть сценарий с родительскими/дочерними вложенными контроллерами. У меня нет проблем с доступом к родительским свойствам в вложенном html с помощью $parent.vm.property
, но я не могу понять, как получить доступ к родительскому свойству из моего дочернего контроллера.
Я попытался ввести область $scope и затем использовать $scope.$parent.vm.property
, но это не работает?
Может ли кто-нибудь предложить совет?
Ответы
Ответ 1
Если ваш HTML-код подобен ниже, вы можете сделать что-то вроде этого:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
Затем вы можете получить доступ к родительской области следующим образом
function ParentCtrl($scope) {
$scope.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl($scope) {
$scope.parentcities = $scope.$parent.cities;
}
Если вы хотите получить доступ к родительскому контроллеру из своего представления, вы должны сделать что-то вроде этого:
<div ng-controller="xyzController as vm">
{{$parent.property}}
</div>
См. jsFiddle: http://jsfiddle.net/2r728/
Обновление
На самом деле, поскольку вы определили cities
в родительском контроллере, ваш дочерний контроллер наследует все переменные области. Поэтому теоретически вам не нужно вызывать $parent
. Вышеприведенный пример также может быть записан следующим образом:
function ParentCtrl($scope) {
$scope.cities = ["NY","Amsterdam","Barcelona"];
}
function ChildCtrl($scope) {
$scope.parentCities = $scope.cities;
}
В документах AngularJS используется этот подход, здесь вы можете больше узнать о $scope
.
Другое обновление
Я думаю, что это лучший ответ на оригинальный плакат.
HTML
<div ng-app ng-controller="ParentCtrl as pc">
<div ng-controller="ChildCtrl as cc">
<pre>{{cc.parentCities | json}}</pre>
<pre>{{pc.cities | json}}</pre>
</div>
</div>
JS
function ParentCtrl() {
var vm = this;
vm.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl() {
var vm = this;
ParentCtrl.apply(vm, arguments); // Inherit parent control
vm.parentCities = vm.cities;
}
Если вы используете метод controller as
, вы также можете получить доступ к родительской области следующим образом
function ChildCtrl($scope) {
var vm = this;
vm.parentCities = $scope.pc.cities; // note pc is a reference to the "ParentCtrl as pc"
}
Как вы можете видеть, есть много разных способов доступа к $scopes
.
function ParentCtrl() {
var vm = this;
vm.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl($scope) {
var vm = this;
ParentCtrl.apply(vm, arguments);
vm.parentCitiesByScope = $scope.pc.cities;
vm.parentCities = vm.cities;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<div ng-app ng-controller="ParentCtrl as pc">
<div ng-controller="ChildCtrl as cc">
<pre>{{cc.parentCities | json}}</pre>
<pre>{{cc.parentCitiesByScope | json }}</pre>
<pre>{{pc.cities | json}}</pre>
</div>
</div>
Ответ 2
Я только что проверил
$scope.$parent.someProperty
работает для меня.
и это будет
{{$parent.someProperty}}
для представления.
Ответ 3
Когда вы используете синтаксис as
, например ParentController as parentCtrl
, для определения контроллера, затем для доступа к родительской переменной сферы в дочернем контроллере используйте следующее:
var id = $scope.parentCtrl.id;
Где parentCtrl
- это имя родительского контроллера с использованием синтаксиса as
, а id
- это переменная, определенная в том же контроллере.
Ответ 4
В некоторых случаях вам может потребоваться обновить родительские свойства непосредственно в пределах дочернего объекта. например необходимо сохранить дату и время родительского контроля после изменений дочерним контроллером. например Код в JSFiddle
HTML
<div ng-app>
<div ng-controller="Parent">
event.date = {{event.date}} <br/>
event.time = {{event.time}} <br/>
<div ng-controller="Child">
event.date = {{event.date}}<br/>
event.time = {{event.time}}<br/>
<br>
event.date: <input ng-model='event.date'><br>
event.time: <input ng-model='event.time'><br>
</div>
</div>
JS
function Parent($scope) {
$scope.event = {
date: '2014/01/1',
time: '10:01 AM'
}
}
function Child($scope) {
}
Ответ 5
Вы также можете обходить наследование объектов и хранить вещи в "глобальной" области.
Если у вас есть основной контроллер в приложении, который обертывает все остальные контроллеры, вы можете установить "hook" в глобальную область:
function RootCtrl($scope) {
$scope.root = $scope;
}
Затем в любом дочернем контроллере вы можете получить доступ к "глобальной" области с помощью $scope.root
. Все, что вы установили здесь, будет глобально видимым.
Пример:
function RootCtrl($scope) {
$scope.root = $scope;
}
function ChildCtrl($scope) {
$scope.setValue = function() {
$scope.root.someGlobalVar = 'someVal';
}
}
function OtherChildCtrl($scope) {
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="RootCtrl">
<p ng-controller="ChildCtrl">
<button ng-click="setValue()">Set someGlobalVar</button>
</p>
<p ng-controller="OtherChildCtrl">
someGlobalVar value: {{someGlobalVar}}
</p>
</div>
Ответ 6
Я считаю, что у меня было подобное затруднение недавно
function parentCtrl() {
var pc = this; // pc stands for parent control
pc.foobar = 'SomeVal';
}
function childCtrl($scope) {
// now how do I get the parent control 'foobar' variable?
// I used $scope.$parent
var parentFoobarVariableValue = $scope.$parent.pc.foobar;
// that did it
}
Моя настройка была немного другой, но то же самое, вероятно, все равно будет работать
Ответ 7
Возможно, это хромает, но вы также можете просто указать их как на какой-то внешний объект:
var cities = [];
function ParentCtrl() {
var vm = this;
vm.cities = cities;
vm.cities[0] = 'Oakland';
}
function ChildCtrl($scope) {
var vm = this;
vm.cities = cities;
}
Преимущество здесь в том, что изменения в ChildCtrl теперь распространяются обратно на данные родителя.
Ответ 8
Реки ребенка автоматически получают доступ к свойствам $scope. Вы можете получить к ним доступ, как обычно.
свойства родительского элемента несколько более сложны для модификации. Я бы предложил использовать сеттер для изменения свойства родителя. Если вы измените его, как обычно, (просто назначив значение), он создаст копию с локальным охватом с новым значением вместо изменения существующего в родительском объекте.
function ParentCtrl($scope) {
$scope.cities = ["NY", "Amsterdam", "Barcelona"];
}
function ChildCtrl($scope) {
$scope.parentcities = $scope.$parent.cities;
}
Вы также можете создать сервис.
Ввести службу в обоих контроллерах и сохранить ссылку на службу в области контроллеров. Теперь вы можете получить доступ к данным как в представлении, так и в контроллерах.
yourApp.service("sharedService", function() {
this.cities = ["NY", "Amsterdam", "Barcelona"];
})
yourApp.controller("parentController", function(sharedService) {
$scope.sharedService = sharedService;
});
yourApp.controller("childController", function(sharedService) {
$scope.sharedService = sharedService;
});
Теперь все, что вы хотите "разделить" между двумя контроллерами/родительскими дочерними контроллерами, также может быть размещено внутри службы.