javascript - Angular2 - 组件变量/组件类属性的双向数据绑定(bind)?

标签 javascript angular data-binding 2-way-object-databinding

在 Angular2(Beta 6)中,我有一个主菜单组件。

<mainmenu></mainmenu>

我想为宽或窄绑定(bind)一个 bool 值。所以我把它变成了:

<mainmenu [(menuvisible)]="true"></mainmenu>

但我想要的(我认为)是绑定(bind)到一个 javascript 类属性(因为我可能有其他东西要绑定(bind)但希望通过在组件中使用单个类来保持整洁)。

我得到一个错误

EXCEPTION: Template parse errors: Invalid property name 'menumodel.visible' ("

][(menumodel.visible)]="menumodel.visible">

如果我尝试对单个变量而不是类进行相同的操作,我会得到:

Template parse errors: Parser Error: Unexpected token '='

然而,这(单向绑定(bind)?)似乎确实有效(但我可能想触发菜单从另一个组件变宽/变窄,所以我觉得这应该是双向数据绑定(bind)属性):

<menu [vis]="true"></menu>

这是我的菜单组件的一部分:

@Component({
    selector: 'menu',
    templateUrl: './app/menu.html',
    providers: [HTTP_PROVIDERS, ApplicationService],
    directives: [ROUTER_DIRECTIVES, FORM_DIRECTIVES, NgClass, NgForm]
})
export class MenuComponent implements OnInit {

    mainmenu: MainMenuVM;

    constructor(private _applicationService: ApplicationService) {
        this.mainmenu = new MainMenuVM();
    }

    // ...ngOnInit, various functions

}

这是我的 MainMenu View 模型类

export class MainMenuVM {
    public visible: boolean;
    constructor(
    ) { this.visible = true; }
}

我正在尝试创建一个包含图标和文本的菜单,但可以缩小到只显示图标。我会将此事件向上发送到父组件,以更改菜单旁边容器的位置。触发内容容器最大化将触发菜单变窄 - 我并不是说这是最好的方法,但我想在深入之前解决这个特定问题。

请注意:我在这里没有对输入控件进行数据绑定(bind) - 只是对组件进行数据绑定(bind),这样我就可以修改 UI。

这是来自 Angular 备忘单

<my-cmp [(title)]="name">   
Sets up two-way data binding. Equivalent to: <my-cmp [title]="name" (titleChange)="name=$event">

提前致谢!

更新

整合已接受答案中的代码,并在此处针对我的特定用例进行调整,最终工作代码:

app.html

...header html content

// This is what I started with
<!--<menu [menuvisible]="true" (menuvisibleChange)="menuvisible=$event"></menu>-->

// This is two way data binding
// 1. Banana-in-a-box is the input parameter
// 2. Banana-in-a-box is also the output parameter name (Angular appends it's usage with Change in code - to follow shortly)
// 3. Banana-in-a-box is the short hand way to declare the commented out code
// 4. First parameter (BIAB) refers to the child component, the second refers the variable it will store the result into.
// 5. If you just need an input use the remmed out code with just the first attribute / value
<menu [(menuvisible)]="menuvisible"></menu>

.. div content start 
<router-outlet></router-outlet>
.. div content end 

app.component.ts(根目录)

export class AppComponent implements OnInit{
   menuvisible: Boolean;
}

menu.component.ts(根的子级)

export class MenuComponent implements OnInit {
    // Parameters - notice the appending of "Change"
    @Input() menuvisible: boolean;
    @Output() menuvisibleChange: EventEmitter<boolean> = new EventEmitter<boolean>();

    // Init
    ngOnInit() {
        // Populate menu - fetch application list       
        this.getApplications();

        // Initially we want to show/hide the menu depending on the input parameter
        (this.menuvisible === true) ? this.showMenu() : this.hideMenu();
    }

    //...more code
}

menu.html

<div id="menu" [ngClass]="menuStateClass" style="position: absolute; top:0px; left: 0px;z-index: 800; height: 100%; color: #fff; background-color: #282d32">
    <div style="margin-top: 35px; padding: 5px 0px 5px 0px;">

        <ul class="menuList" style="overflow-x: hidden;">
            <li>IsMenuVisible:{{menuvisible}}</li>
            <li style="border-bottom: 1px solid #3d4247"><a (click)="toggleMenu()"><i class="fa fa-bars menuIcon" style="color: white; font-size: 16px;"></i></a></li>
            <li *ngFor="#app of applications">
                <a [routerLink]="[app.routerLink]">
                    <i class="menuIcon" [ngClass]="app.icon" [style.color]="app.iconColour" style="color: white;"></i>
                    <span [hidden]="menuStateTextHidden">{{ app.name }}</span>
                </a>
            </li>
        </ul>

    </div>
</div>

记得导入你需要的东西,例如

import {Component, EventEmitter, OnInit, Input, Output} from 'angular2/core';

强烈推荐 You Tube 上的这个视频: Angular 2 Tutorial (2016) - Inputs and Outputs

最佳答案

对于双向绑定(bind)你需要这样的东西:

@Component({
    selector: 'menu',
    template: `
<button (click)="menuvisible = !menuvisible; menuvisibleChange.emit(menuvisible)">toggle</button>
<!-- or 
   <button (click)="toggleVisible()">toggle</button> -->
`,
    // HTTP_PROVIDERS should now be imports: [HttpModule] in @NgModule()
    providers: [/*HTTP_PROVIDERS*/, ApplicationService],
    // This should now be added to declarations and imports in @NgModule()
    // imports: [RouterModule, CommonModule, FormsModule]
    directives: [/*ROUTER_DIRECTIVES, FORM_DIRECTIVES, NgClass, NgForm*/]
})
export class MenuComponent implements OnInit {
    @Input() menuvisible:boolean;
    @Output() menuvisibleChange:EventEmitter<boolean> = new EventEmitter<boolean>();

    // toggleVisible() {
    //   this.menuvisible = !this.menuvisible;       
    //   this.menuvisibleChange.emit(this.menuvisible);
    // }
}

像这样使用它

@Component({
  selector: 'some-component',
  template: `
<menu [(menuvisible)]="menuVisibleInParent"></menu>
<div>visible: {{menuVisibleInParent}}</div>
`
  directives: [MenuComponent]
})
class SomeComponent {
  menuVisibleInParent: boolean;
}

关于javascript - Angular2 - 组件变量/组件类属性的双向数据绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35639650/

相关文章:

angular - 链接 Angular 4 和 OpenLayers 4

data-binding - 了解 AngularJS 中的双向数据绑定(bind)

php - 检查而不是在生成的数据中打印 JavaScript?

arrays - 在 Angular 上执行 GET 请求时出现此错误 : Cannot find a differ supporting object '[object Object]

angular - 如何将外部 JS 文件包含到 angular5?

wpf - 公开依赖项属性

.net - 如何创建 ListView 的 SelectedItem 属性的双向链接?

javascript - 如何将 Json 数组传递给 IN 运算符的 JPQLWhere 子句?

javascript - appendTo - 旁边而不是下面

javascript - 我可以将四个功能合二为一吗?