首页 文章

NativeScript单向数据绑定不会更新视图

提问于
浏览
0

这对我来说似乎是一个非常简单的案例,但我显然错过了一些东西 . 我有一个模型绑定到视图 . 然后我用Http调用加载模型 . 为什么View不更新?我认为这是单向约束的全部要点 .

我已经确认我正在收到我希望通过http调用获得的数据 .

Update 我在屏幕上添加了一个按钮,数据绑定实际上会在按钮按下时用两个字段的http加载数据更新屏幕,即使按钮方法只设置其中一个值 . 所以要么's a bug in NativeScript or I'没有做错事 .

Update 2 只需单击按钮即可触发绑定 . 我已经修改了代码以使用空的tap处理程序,只需单击该按钮就可以绑定它 .

打字稿

import { Component, ChangeDetectionStrategy, OnInit } from "@angular/core";
import { Job } from "../../shared/customer/job";
import { Http, Headers, Response } from "@angular/http";
import { Observable } from "rxjs/Rx";

@Component({
    selector: "my-app",
    templateUrl: "pages/job-details/job-details.html",
    changeDetection: ChangeDetectionStrategy.OnPush
})

export class JobDetailsComponent implements OnInit {
    job: Job;
    salesAssociateName: string = "x";

    constructor(private http: Http) {
        this.job = new Job();
    }

    ngOnInit() {
        this.getJob(1234);
    }

    getJob(leadId: number) {
        var url = "https://url-not-for-you/job?franchiseeid=48&leadid=" + leadId;
        var headers = this.createRequestHeader();

        this.http.get(url, { headers: headers }).map(response => response.json())
            .do(data => this.setData(data[0]))
            .subscribe(
                () => this.success(),
                (error) => this.error()
            );
    }

    private createRequestHeader() {
        let headers = new Headers();
        headers.append("AuthKey","blah");
        headers.append("AuthToken", "blee");

        return headers;
    }

    setData(job) {
        this.job.FullName = job["FullName"];
        this.job.SalesAssociateName = job["SalesAssociateName"];
        this.salesAssociateName = this.job.SalesAssociateName;

        console.log("Found job for customer: " + job["FullName"]);
    }

    success() {
        // nothing useful
    }

    error() {
        alert("There was a problem retrieving your customer job.");
    }

    changeSA() {
    }
}

HTML

<StackLayout>
    <Label [text]="job.FullName"></Label>
    <Label [text]="salesAssociateName"></Label>
    <Button text="Push" (tap)="changeSA()"></Button>
</StackLayout>

1 回答

  • 2

    您的代码将按预期使用默认的ChangeDetectionStrategy . 但是,您已将策略更改为 onPush

    为了使您的绑定按预期在默认的changeStrategy delete 中进行以下操作

    changeDetection: ChangeDetectionStrategy.OnPush
    

    或改为

    changeDetection: ChangeDetectionStrategy.Default
    

    关于Angular-2 ChangeDetectionStrategy herehere的更多信息

    如果你仍然想使用onPush而不是默认策略,那么你的属性应该被声明为 @input() 并且一旦进行了更改(在你的情况下在setData中),标记为 markForCheck()

    从按钮点击触发绑定工作的原因是因为应用程序状态更改可以通过以下方式触发:

    • 活动 - 点击,滑动,

    • XHR - 从远程服务器获取数据

    • 计时器 - 例如的setTimeout()

    出于测试目的,如果有人对如何使用 onPush 实现场景感兴趣,请参阅示例代码:

    import { Component, ChangeDetectionStrategy, ChangeDetectorRef, OnInit, NgZone, Input } from "@angular/core";
    import { Http, Headers, Response } from "@angular/http";
    import { Observable as RxObservable } from "rxjs/Rx";
    import "rxjs/add/operator/map";
    import "rxjs/add/operator/do";
    
    @Component({
        selector: "my-app",
        templateUrl: "app.component.html",
        changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class AppComponent implements OnInit {
        @Input() public job: any = { salesAssociateName: "default job" };
        @Input() public salesAssociateName: string = "default name";
    
    
        constructor(private http: Http, private change:ChangeDetectorRef) { }
    
        ngOnInit() {
            this.getJob();
        }
    
        getJob() {
            var url = "http://httpbin.org/get";
            var headers = this.createRequestHeader();
    
            this.http.get(url, { headers: headers })
                .map(response => response.json())
                .do(data => {
                    this.setData();
                }).subscribe(
                    () => this.success(),
                    (error) => this.error()
                );
        }
    
        private createRequestHeader() {
            let headers = new Headers();
            return headers;
        }
    
        setData() {
    
            this.job.salesAssociateName = "NEW job SalesAssociateName";
            this.salesAssociateName = "NEW job FullName";
            this.change.markForCheck();
        }
    
        success() {
            alert("success");
        }
    
        error() {
            alert("There was a problem retrieving your customer job.");
        }
    }
    

相关问题