这是我要做的事情的要点。我有一个带有Dark / Light主题的标题组件,用于Angular2 Material。标题组件位于“主”状态内。我有一个嵌套的< ui-view>标签,我的main.home和其他main.child状态将存在。当我切换isDarkTheme时,main得到它,[class.mg2-darkTheme] =“isDarkTheme”切换工作,但是生活在主要的孩子们。不要,他们的主题不会改变。
/ *如果有另一种方法,我会很高兴听到它,但我一直在尝试使用我的AngularJS1.x技能,试图在父母和孩子之间双向绑定数据,至今尚未成功...... * /
在AngularJS1.x和ui-router中传递数据非常直观。只需解析一个对象,甚至更好,获取$ scope。$ parent.main,你就可以访问子路由上的整个父对象,双向绑定。 Angular2和ui-router有点挑战性。
我在ui-router https://ui-router.github.io/ng2/上找到的文档只是指向路由参数。但我没有导航到:id。我只想在父< =>之间绑定数据child(只是一个简单的布尔切换)。
我正在尝试将数据(... isDarkTheme的布尔值)从父“main”状态的组件“header-menu”传递给父“main”本身,然后传递到子状态' main.home”。
'main.component'有一个isDarkTheme布尔值,它是'header-menu.component'的@Input,在那里切换,然后回到main。
头-menu.component.ts:
SELECT
calls.Id,
calls.DateBegin,
calls.DateEnd,
calls.Phone,
contacts.Name
FROM
calls LEFT JOIN contacts ON
RIGHT(calls.Number, 8) = RIGHT(contacts.Phone1, 8) OR
RIGHT(calls.Number, 8) = RIGHT(contacts.Phone2, 8)
WHERE
calls.UserId = 1 AND contacts.UserId = 1
GROUP BY
calls.Id
ORDER BY
calls.DateBegin DESC;
头-menu.component.html:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'header-menu',
templateUrl: './header-menu.component.html',
styleUrls: ['../shared/material-theme.scss', './header-menu.component.scss']
})
export class HeaderMenuComponent {
// this is set in main and passed in as attr in main.html
@Input() headerIsDarkTheme: boolean;
// guessing I pass this bool back out with emitter...
@Output() themeOnClicked = new EventEmitter<boolean>;
notifyParentTheme(): void {
this.headerIsDarkTheme = !this.headerIsDarkTheme;
this.notifyParentTheme.emit(this.headerIsDarkTheme);
}
}
main.component.ts:
<div [class.mg2-darkTheme]='headerIsDarkTheme'>..</div>
<button (click)="notifyParentTheme()"
main.component.html:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'main-cmp',
templateUrl: './main.component.ts',
styleUrls: ['../shared/material-theme.scss']
})
export class MainComponent implements OnInit {
isDarkTheme: boolean;
NgOnInit(){
// initializing here... perhaps a better place to init...
this.isDarkTheme = false;
}
listenForTheme( isDarkTheme: boolean ): void {
this.isDarkTheme = isDarkTheme;
/****************************************
* MAIN QUESTION
* How do I pass this theme down to the main.home state?
*
****************************************/
}
}
main.home.component.html:
<div [class.mg2-darkTheme]="isDarkTheme">
<!-- pass in isDarktheme from 'main' into header-menu, header receives with headerIsDarkTheme -->
<!-- receive toggled theme from header-menu, event (notifyParentTheme) gets the event, then sends to method processHeaderTheme( $event ) -->
<header-menu [ headerIsDarkTheme ]="isDarkTheme"
( themeOnClicked )="listenForTheme( $event )">
</header-menu>
<!-- I want to pass this into the ui-view to toggle the theme -->
<!-- WHY? because the Angular2 Material theme doesn't work in ui-view -->
<!-- But darkThem works just using a component like <home-cmp></home-cmp> -->
<ui-view></ui-view>
</div>
main.home.component.ts
<div [class.mg2-darkTheme]="homeIsDarkTheme">...</div>
states.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'home-cmp',
templateUrl: './home.component.html'
})
export class HomeComponent {
@Input() homeIsDarkTheme: boolean;
}
router.config.ts
...
export const mainState = {
name: 'main',
// url: '/main',
component: MainComponent
};
export const homeState = {
name: 'main.home',
url: '/home',
component: HomeComponent
};
app.module.ts .... const INITIAL_STATES = [ mainState, 老家 ];
import {UIRouter} from "ui-router-ng2";
import {Injector, Injectable} from "@angular/core";
/** UIRouter Config */
export function uiRouterConfigFn(router: UIRouter, injector: Injector) {
// If no URL matches, go to the `hello` state by default
router.urlService.rules.otherwise({ state: 'main' });
}
答案 0 :(得分:-1)
好的,如果我明白你要做什么:
MainComponent提供初始isDarkTheme
并监听HeaderMenuComponent以进行更改
//MainComponent html
<header-menu [ headerIsDarkTheme ]="isDarkTheme"
( themeOnClicked )="listenForTheme( $event )">
</header-menu>
//MainComponent
isDarkTheme: boolean = false; //you can initialize isDarkTheme here
listenForTheme( isDarkTheme: boolean ): void {
this.isDarkTheme = isDarkTheme;
}
HeaderMenuComponent获取headerIsDarkTheme
并通知main进行任何更改:
//HeaderMenuComponent html
<button (click)="notifyParentTheme()">Notify Parent</button>
//HeaderMenuComponent
@Input() headerIsDarkTheme: boolean;
@Output() themeOnClicked = new EventEmitter<boolean>; //you'll emit a boolean not a type headerIsDarkTheme
notifyParentTheme(): void {
this.headerIsDarkTheme = !this.headerIsDarkTheme;
this.themeOnClicked.emit(this.headerIsDarkTheme); //change notifyParentTheme to themeOnClicked
}
编辑:所以你的主要问题是如何将headerIsDarkTheme传递给HomeComponent。
//HomeComponent html
<div [class.mg2-darkTheme]="homeIsDarkTheme">...</div>
您似乎没有HomeComponent和MainComponent之间的直接交互,因此HomeComponent中的输入无用
export class HomeComponent {
@Input() homeIsDarkTheme: boolean;//you can't get your theme with this input
}
我建议您create a service。你的代码有点乱(没有冒犯),创建服务会更具可读性。
也就是说,如果你想坚持输入和输出,在Home和Main之间创建一个直接关系,并从Main发出值。就像是:
所以你这里不需要任何路由器...如果这个答案不能按你的意愿工作,我强烈建议你提供一个探索者