每个组件不共享服务实例

时间:2017-02-09 18:22:52

标签: angular

目标:我正在尝试创建一个具有可订阅数组(BehaviorSubject)的服务,这样当我更新服务中的数据时,更改会反映在正在使用的客户端组件中它。我决定在添加或更改项目时首先尝试在服务器中保留持久性列表,然后我会担心保持数据与服务器一致。

问题:

workCategories:Rx.BehaviorSubject>在服务中似乎没有保留它分配的数据。从第一个客户端组件调用它,然后当第二个客户端组件使用该服务时,workCategories再次为null。

服务

import { Component, Injectable } from "@angular/core";
import { Http, Response, Headers, RequestOptions, RequestMethod, Request } from "@angular/http";
import { WorkCategory } from "./models";
import { Observable } from "rxjs/Observable";
import * as Rx from "rxjs/Rx";


@Injectable()
export class WorkCategoryService {

    public workCategories: Rx.BehaviorSubject<Array<WorkCategory>>;

    private _workCategories: Array<WorkCategory> = [];

    constructor(public http: Http) {
        console.log("!!!!WorkCat Service Constructor Called!!!");
        this.getWorkCategories();
    }

    addWorkCategory(wc: WorkCategory): number {
        //** when this is called after component is instantiated and getWorkCategories() is called this.workCategories is null
        console.log("Add Work Category Called in Service for \"" + wc.name + "\"");

        let newID: number;
        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        let options = new RequestOptions({ headers: headers });
        let blah = this.http.post('./api/workcategories', JSON.stringify(wc), options).subscribe((res: Response) => newID = res.json());
        if (this._workCategories != null) {
            console.log("Added to private");
            this._workCategories.push(wc);
        }

        //** fails here and the page is reloaded due to this.workCategories being null
        this.workCategories.next(this._workCategories);

        return newID;
    }

    getWorkCategories(): Observable<Array<WorkCategory>> {
        console.log("Get Work Category Called in Service");

        var blah = this.http.get('./api/workcategories')
            .map(this.WorkCategoriesResponseMapper)
        console.log("Get Work Category Done in Service");
        return blah;

    }

    WorkCategoriesResponseMapper(response: Response) {
        var temp = response.json();

        if (this.workCategories == null) {            
            this._workCategories = temp;           
            this.workCategories = new Rx.BehaviorSubject(this._workCategories);  
        }
        else {
            this._workCategories = temp;
            this.workCategories.next(this._workCategories);
        }
        return temp;
    }
}

第一个客户端组件

这会调用this.workCatServ.getWorkCategories()并订阅它。

import { Component, Input, Injectable, ViewChild, EventEmitter, Output, } from "@angular/core";
import { Http, Response, Headers, RequestOptions, RequestMethod, Request } from "@angular/http";
import { WorkCategory } from "./models";
import { WorkCategoryService } from "./workcategories.service";
//import { Observable } from 'rxjs/Observable';
import * as Rx from "rxjs/Rx";
import { TreeNode, MenuItem, Message } from 'primeng/primeng';
import { CategoryAdderUpdateComponent } from "./category-adder-update.component";


@Component({
    selector: 'workcategories_view',
    //providers: [WorkCategoryService],
    templateUrl: './app/workcategories-view.html'
})

@Injectable()
export class WorkCategoriesViewComponent {
    @ViewChild(CategoryAdderUpdateComponent) private CategoryCU: CategoryAdderUpdateComponent;
    @Output() GrowlMsg = new EventEmitter<Message>();
    workCats: Array<WorkCategory>;
    tree: TreeNode[];
    selectedNode: TreeNode;
    selectedCategory: WorkCategory = new WorkCategory(-1,"Blank",-2);
    contextMenuItems: MenuItem[];
    CUWorkCatVisible: boolean = false;
    CUWorkCatEdit: boolean = false;
    CUViewHeader: string;

    constructor(public http: Http, private workCatServ: WorkCategoryService) {
    }

    ngOnInit() {
        console.log("Work Categories view called");
        this.workCatServ.getWorkCategories().subscribe(result => this.convertToTreeNodes(result), error => console.error(error), () => { });

        this.contextMenuItems = [
            {
                label: 'Add',
                icon: 'fa-plus',
                command: (event) => { this.displayAddWorkCat() }
            },
            {
                label: 'Edit',
                icon: 'fa-edit',
                command: (event) => { this.displayEditWorkCat() }        
            },
            {
                label: 'Delete',
                icon: 'fa-eraser',
                command: (event) => { this.displayDeleteWorkCat() } 

            }
        ];

    }


    displayAddWorkCat() {

        this.selectedCategory = this.workCats.find(b => b.id == this.selectedNode.data);
        //console.log("Add " + this.selectedCategory.name);
        this.CategoryCU.AddView(this.selectedCategory);
        this.CUViewHeader = "Add Work Category";
        /*this.workCatServ.findWorkCategorey(this.selectedNode.data).map(result => {
            console.log("Done");
            this.selectedCategory = result;

        });
        */

        this.CUWorkCatVisible = true;

    }

    displayEditWorkCat() {                
        this.selectedCategory = this.workCats.find(x => x.id == this.selectedNode.data);
        //console.log("Edit " + this.selectedCategory.name);
        this.CategoryCU.UpdateView(this.selectedCategory);
        this.CUViewHeader = "Edit \"" + this.selectedCategory.name + "\" Work Category";

        /*this.workCatServ.findWorkCategory(this.selectedNode.data).map(result => {
            console.log("Done");
            this.selectedCategory = result;

        });*/

        this.CUWorkCatVisible = true;

    }

    displayDeleteWorkCat() {
        console.log("Delete");

    }

    passUpGrowlMsg(msg: Message) {
        this.GrowlMsg.emit(msg);
    }

    MyTreeWalker(nodeId: number = 0, parentNode: TreeNode = null): boolean {
        let blah = this.workCats.filter(x => x.parentId == nodeId);
        if (blah.length == 0) {
            //console.log("Node " + nodeId + " is leaf");
            return false;
        }

        //console.log("Node " + nodeId + " is branch, " + blah.length + " children");


        if (nodeId != 0) {

            for (var b of blah) {
                var TempNode: TreeNode = { label: b.name, data: b.id, parent: parentNode, children: [] };

                this.MyTreeWalker(b.id, TempNode);
                //console.log("Control Passed Back");
                parentNode.children.push(TempNode);
                //console.log("Pass End");
            }
        } else {
            for (var c of blah) {
                var TempNode: TreeNode = { label: c.name, data: c.id, parent: parentNode, children: [] };
                this.MyTreeWalker(c.id, TempNode);
                //console.log("R - Control Passed Back");
                this.tree.push(TempNode);
                //console.log("R - Pass End");
            }                      
        }
        //console.log("Node: " + nodeId + " Exit");
        return true;
    }

    convertToTreeNodes(cats: WorkCategory[]) {
        console.log("Tree Updated Called");
        this.tree = new Array<TreeNode>();
        this.workCats = cats;

        this.MyTreeWalker();
    }
}

第二个客户端组件

这会在服务中调用addWorkCategory()

import { Component, EventEmitter, Output, Input } from "@angular/core";
import { Http, Response } from "@angular/http";
import { WorkCategory} from "./models";
import { WorkCategoryService } from "./workcategories.service";
import { Message } from 'primeng/primeng';
import 'rxjs/add/operator/map';

@Component({
    selector: 'category-adder-update',
    //providers: [WorkCategoryService],
    templateUrl: './app/category-adder-update.html'

})

export class CategoryAdderUpdateComponent {

    @Output() GrowlMsg = new EventEmitter<Message>();
    edit: boolean;
    workcategories: Array<WorkCategory> = [];
    tempCategory: WorkCategory;
    parentCategory: WorkCategory;
    buttonText: string = "Blanky Blank";



    constructor(public http: Http, public workCategoriesServ: WorkCategoryService) {
        this.tempCategory = new WorkCategory(null,"",null);
        console.log("Category Adder-Update Called");
    }

    AddView(parentCat: WorkCategory) {
        this.edit = false;
        this.parentCategory = parentCat
        this.tempCategory = new WorkCategory(null, "", parentCat.id);
        this.buttonText = "Add Work Category";

    }

    UpdateView(cat: WorkCategory) {
        this.edit = true;
        this.parentCategory = null;
        this.tempCategory = cat;
        this.buttonText = "Update Work Category";
    }

    blahSubmit() {
        if (this.edit) {
            this.updateWorkCategory();
        } else {
            this.addWorkCategory();
        }
    }


    getWorkCategories() {
        console.log("jobs get called");
        this.workCategoriesServ.getWorkCategories().subscribe(
            result => this.workcategories = result,
            error => console.error,
            () => console.log('workcategories loaded: ' + this.workcategories.length));
    }

    addWorkCategory(): void {    
        this.GrowlMsg.emit({ severity: 'info', summary: 'Category Added', detail: "Category " + this.tempCategory.name + " added to " + this.parentCategory.name });       
        if (this.workCategoriesServ.addWorkCategory(this.tempCategory) != null) {
            console.log("New Work Category Submitted");
        }
        else {
            console.error("New Work Category NOT Submitted");
        }

    }


}

应用模块

@NgModule({
    imports: [BrowserModule, HttpModule, FormsModule, DataTableModule, CalendarModule, TreeModule, TabViewModule, GrowlModule, DialogModule, ContextMenuModule, RouterModule.forRoot(appRoutes) ], 
    declarations: [AppComponent, TicketAdderComponent, JobsViewComponent, TimeEntriesViewComponent, WorkCategoriesViewComponent, CategoryAdderUpdateComponent],
    providers: [WorkCategoryService],
    entryComponents: [TicketAdderComponent],
    bootstrap: [AppComponent ]
})
export class AppModule { }

1 个答案:

答案 0 :(得分:2)

您在每个组件中提供服务。您要做的是在AppModule中提供服务,然后两个组件将共享相同的服务。