Angularjs 如何在不使用$scope的情况下在同级组件之间传递数据?
我正在以这种方式制作一个包含3个子组件的组件:Angularjs 如何在不使用$scope的情况下在同级组件之间传递数据?,angularjs,components,angularjs-controlleras,Angularjs,Components,Angularjs Controlleras,我正在以这种方式制作一个包含3个子组件的组件: <header-component> <side-component> <main-component> 主组件包含英雄列表。 header组件包含两个按钮,用于将主组件上的视图切换为列表视图或网格视图 现在的问题是将数据从header组件传递到main组件。因此,当我单击“网格”按钮时,主要内容上的视图应更改为“网格视图”,行视图也是如此 如何在angular 1.5中的子组件之间传递数据 使用自定义事件
<header-component>
<side-component>
<main-component>
主组件包含英雄列表。
header组件包含两个按钮,用于将主组件上的视图切换为列表视图或网格视图
现在的问题是将数据从header组件传递到main组件。因此,当我单击“网格”按钮时,主要内容上的视图应更改为“网格视图”,行视图也是如此
如何在angular 1.5中的子组件之间传递数据 使用自定义事件来实现这一点。 您可以使用事件分派器
$emit(name,args)在应用程序中传递消息;或$broadcast(名称,args)代码>
您可以使用方法$on(name,listener)侦听此事件
希望能有帮助
参考:
例如:
您可以从标题组件通知如下更改
$rootScope.$emit("menu-changed", "list");
您可以在主组件指令中监听更改,如
$rootScope.$on("menu-changed", function(evt, arg){
console.log(arg);
});
组件方法
我建议您采用角度2分量法和使用/方法。如果这样做,您将能够轻松地迁移到Angular 2,因为组件在概念上是相同的(只是语法不同)。这就是你做这件事的方法
所以我们基本上希望header和主要组件与header共享一段状态,以便能够更改它。我们可以使用几种方法使其工作,但最简单的方法是使用中间父控制器属性。因此,假设父控制器(或组件)定义了头(可读取和修改)和主(可读取)组件都要使用的视图属性
标题组件:输入和输出
下面是简单标题组件的外观:
.component('headerComponent', {
template: `
<h3>Header component</h3>
<a ng-class="{'btn-primary': $ctrl.view === 'list'}" ng-click="$ctrl.setView('list')">List</a>
<a ng-class="{'btn-primary': $ctrl.view === 'table'}" ng-click="$ctrl.setView('table')">Table</a>
`,
controller: function() {
this.setView = function(view) {
this.view = view
this.onViewChange({$event: {view: view}})
}
},
bindings: {
view: '<',
onViewChange: '&'
}
})
主要组件:输入
主组件更简单,它只需要定义它接受的输入:
.component('mainComponent', {
template: `
<h4>Main component</h4>
Main view: {{ $ctrl.view }}
`,
bindings: {
view: '<'
}
})
.component('mainponent'{
模板:`
主要成分
主视图:{{$ctrl.view}
`,
绑定:{
视图:“尽管父组件方法(通过属性传递数据)是一个完美有效但很好的实现,我们可以使用存储工厂以更简单的方式实现同样的功能。
基本上,数据由存储
保存,这在两个组件范围内都被引用,当状态发生变化时,可以对UI进行反应式更新
例如:
然后,在您的组件中,您应该有如下内容:
angular
.module('YourApp')
.component('headerComponent'{
//注入存储依赖项
管理员(商店){
//获取存储引用并将其绑定到范围:
//现在,对存储数据所做的每一次更改都将
//自动更新您的组件UI
this.state=Store.get();
//…您的代码
},
模板:`
...
...
...
`
})
.component('main component'{
//这里也一样,我们需要注入商店
管理员(商店){
//“切换视图”按钮的回调
this.switchViewType=(type)=>{
//更改存储数据:
//不需要通知什么的
set({viewType:type});
};
//…您的代码
},
模板:`
切换到电网
切换到世界其他地区
...
`
如果要查看工作示例
这样,您还可以启用2个或N个组件之间的通信。您只需:
注入存储依赖项
确保将存储数据链接到组件范围
就像上面的例子(
)
在现实世界中,典型的应用程序需要管理大量数据,因此以某种方式对数据域进行逻辑拆分更有意义。按照相同的方法可以添加更多的存储工厂。例如,管理当前记录的用户信息和外部资源(即目录)您可以构建一个UserStore
加上一个CatalogStore
——或者UserModel
和CatalogModel
;这些实体也是集中与后端通信、添加自定义业务逻辑等事务的好地方。Store
将全权负责数据管理>工厂
请记住,我们正在对存储数据进行变异。虽然这种方法非常简单明了,但可能无法很好地扩展,因为它会产生。如果您想要更高级的东西(不变性、纯函数、单状态树等),请查看,或者如果您最终想要切换到Angular 2,请查看
希望这有帮助!:)
你不必按角度2的方式来做,因为以防万一
有时你会迁移…如果你觉得这样做有意义的话就去做
完全一样。为了明确起见,Subash Selvaraj的建议不是我推荐的。相反,我建议你采用角度2分量法,并使用输入/输出法。如果你这样做,你将能够轻松迁移到ng2。如果你感兴趣,我可以发布答案。否则,你当然可以o自定义事件,但我认为不是这样。我使用的是controllerAs语法和vm变量,所以我不想使用$scope或$rootscope。我很想看看你是如何解决这个问题的。我假设很多开发人员会发现你的答案很有用。所以请这样做。我很想看看子组件如何相互通信实际上,我不想在这个问题上使用$scope或$rootscope。我可以使用controllerAs语法和vm变量使其工作吗?@BesaNeziri如果是这样,您可以使用factory在它们之间共享数据
.component('mainComponent', {
template: `
<h4>Main component</h4>
Main view: {{ $ctrl.view }}
`,
bindings: {
view: '<'
}
})
<header-component view="root.view" on-view-change="root.view = $event.view"></header-component>
<main-component view="root.view"></main-component>
angular
.module('YourApp')
// declare the "Store" or whatever name that make sense
// for you to call it (Model, State, etc.)
.factory('Store', () => {
// hold a local copy of the state, setting its defaults
const state = {
data: {
heroes: [],
viewType: 'grid'
}
};
// expose basic getter and setter methods
return {
get() {
return state.data;
},
set(data) {
Object.assign(state.data, data);
},
};
});
angular
.module('YourApp')
.component('headerComponent', {
// inject the Store dependency
controller(Store) {
// get the store reference and bind it to the scope:
// now, every change made to the store data will
// automatically update your component UI
this.state = Store.get();
// ... your code
},
template: `
<div ng-show="$ctrl.state.viewType === 'grid'">...</div>
<div ng-show="$ctrl.state.viewType === 'row'">...</div>
...
`
})
.component('mainComponent', {
// same here, we need to inject the Store
controller(Store) {
// callback for the switch view button
this.switchViewType = (type) => {
// change the Store data:
// no need to notify or anything
Store.set({ viewType: type });
};
// ... your code
},
template: `
<button ng-click="$ctrl.switchViewType('grid')">Switch to grid</button>
<button ng-click="$ctrl.switchViewType('row')">Switch to row</button>
...
`