我正在使用AngularJS和ui-router构建一个单页Web应用程序。我有两个不同的州,一个父母和一个孩子。在父状态“ spots”中,用户可以从ng-repeat中进行选择,并使用范围显示其选择。
当用户进行选择时,我用ng键单击fire一个使用$ state.go加载子状态“明细”的函数。我想在子状态下加载它们的选择,但范围数据似乎消失了?
我尝试为每个状态使用相同的控制器。 ui-sref也不起作用。
来自父州HTML模板
<div class="card-column mx-0" data-ng-click="makeSelection = true">
<div class="card mx-0 mb-3 ng-scope" data-ng-click="showSpot(spot);" data-ng-repeat="spot in spots | filter:{'game':gameID} | filter:{'walking':distanceID} | filter:{'vehicle':vehicleID} | orderBy:'price' | filter as results">
<div class="row no-gutters">
<div class="col-sm-12 col-md-3 col-lg-3">
<img src="{{ spot.image }}" alt="parking spot"/>
</div>
<div class="col-sm-12 col-md-9 col-lg-9">
<div class="card-body px-4 pt-4">
<h6 class="text-small-extra text-muted font-weight-normal text-uppercase"><span style="letter-spacing: .05rem;">{{ spot.type }}</span></h6>
<h5 class="card-title">{{ spot.address }}</h5>
<h4 class="text-muted float-md-right">${{ spot.price }}<span style="font-size: 1rem; font-weight: 400">/day</span></h4>
</div>
</div>
</div>
</div>
控制器的摘录
$scope.showDetails = function() {
$state.go('spots.details'); //my route...
}
$scope.showSpot = function(spot) {
$scope.spot = spot;
$scope.showDetails();
}
来自app.js的代码段
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/")
$stateProvider
.state('spots',{
url: '/',
templateUrl: "/parkit/master/spots-available.html",
controller: 'parkitController'
})
.state('details', {
parent: 'spots',
url: '/details',
templateUrl: '/parkit/master/details.html',
})
.state('statetwo', {
url: '/statetwo',
template: '<h1>State Two</h1>',
controller: 'parkitController'
});
})
我希望用户选择会在触发ng-click之后显示在子状态上。
答案 0 :(得分:1)
您需要了解原型继承的工作方式。当父母使用
将属性值放在作用域上时$scope.value = 'something';
在子组件中,如果您访问$ scope.value,则继承链将找到$ scope.value。
如果孩子设置了
$scope.otherValue = 'something';
如果遵循继承链,则不会找到otherValue的值并在子作用域上创建属性,而不是在继承的原型上创建属性,因此父组件和父级的任何其他子项都看不到它。
您可以使用所谓的原型继承的点规则。如果父级在作用域上创建了一个称为数据的对象
$scope.data = { value: 'something' };
现在,如果孩子将属性放在数据对象上
$scope.data.otherValue = 'something';
它会查找数据对象,并在继承链中找到它,并且因为您正在向对象的实例添加属性,因此它对父级和父级的任何子级都是可见的。
let parent = {
value: 'some value',
data: { value: 'some value' }
};
let child = Object.create(parent);
console.log(child.value); // Finds value on the prototype chain
child.newValue = 'new value'; // Does not affect the parent
console.log(parent.newValue);
child.data.newValue = 'new value'; // newValue is visible to the parent
console.log(parent.data.newValue);
简短的答案是永远不要注入$ scope并使用controllerAs语法。
要在控制器之间共享数据,请使用注入到两个控制器中的服务。您在服务上具有了Spots集合,并使用路由参数来确定另一个控制器应使用哪个地点,或在另一个控制器上设置的名为currentSpot的服务上具有位置。
服务是您在模块级别创建的单例对象,然后在其依赖项列表中要求它们的所有控制器都将获得相同的实例。它们是在控制器之间共享数据的首选方式,$ scope层次结构势必会引起混乱,因为它们的原型继承性质可能会造成混淆。子级$ scope原型是从其父级继承的,这似乎应该共享数据,但是当子级控制器设置属性时,父级不可见。
您正在学习一种过时的Angular编程方式。不再推荐使用$ scope注入。查看使用组件。组件是具有隔离范围并使用contollerAs语法的控制器的包装。孤立的作用域使人们更清楚地知道数据的来源。
看看我对这个问题的回答
Trying to activate a checkbox from a controller that lives in another controller