需要为角度为4的输入发送的ngModel设置动态值

时间:2018-02-23 14:18:12

标签: javascript angular

有两个地址发货和结算国家/地区。两者都有不同的价值。 组件在这里重复使用。 为此制定了一个精选国家组成部分。

<select-country [addressType]="'shipping'"></select-country>
<select-country [addressType]="'billing'"></select-country>

该类型可以发货或结算。

现在在选择国家

 
import { Component, OnInit,ViewChild, ElementRef,Input  } from '@angular/core';
import { ConfigService } from '../services/config.service';
import { DataService } from '../services/data.service';
import { CheckOutService } from '../services/checkout/check-out.service';
import { HomeService } from './../services/banner/home.service';
import {MdlService} from './../services/material-design-lite/mdl.service';
import { Http } from "@angular/http";
import { apiUrl,used_currency,used_language } from './../services/global.constant';
 import { Router,ActivatedRoute  } from '@angular/router';
import {NgSelectModule, NgOption} from '@ng-select/ng-select';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/switchMap';

declare var componentHandler: any;
@Component({
	moduleId: module.id + '',
  selector: 'select-country',
  templateUrl: './get-country.component.html',
  styleUrls: ['./get-country.component.css'] 
})
export class GetCountryComponent implements OnInit {
 @Input('addressType') addressType; 
 searchQuery: string = '';
  items;va;
  countries = new Array;	
  constructor(public http: Http,public router: Router,
  	public configz: ConfigService,public shared: DataService,
    private checkOutservice: CheckOutService ,
    private service: HomeService, public material:MdlService) { 
     if(this.addressType=='shipping')
     {va=shared.orderDetails.delivery_country}
    else{va=shared.orderDetails.billing_country}
  	 var data = { type: 'null' };
    http.post(this.configz.url + 'getCountries', data).map(res => res.json()).subscribe(data => {
      
      this.items = this.countries = data.data;
      console.log(this.items);
      setTimeout(() => {  this.material.render(); }, 550);
    });
  }
  ngAfterViewInit(){

  }
  ngOnInit() {
  }
  static mdlWrapper(element: ElementRef) {

        componentHandler.upgradeElement(element.nativeElement);
    }
}
                                        <div   tabindex="-1">
                                            <select  [(ngModel)]="shared.orderDetails.delivery_country" name="orderby"  > 
                                             <option *ngFor="let item of items" value=""  >{{ item.countries_name }}</option>
                                                 
                                            </select>
                                        </div>
                                    
共享是在所有组件之间共享的服务。 对于运输shared.orderDetails.delivery_country用于帐单shared.orderDetails.billing_country

如何动态更改ngModel并设置shared.orderDetails。 我只在共享中进行更改,因为有多个组件,他们需要共享相同的服务来保留数据。

编辑:我尝试在Get Country Component中设置变量。编辑它请检查。它不会更新shared.orederDetails。

2 个答案:

答案 0 :(得分:0)

为什么不将<select-country>构建为正确的表单控件?这样你就可以使用ngModel绑定而忘记细节。像这样:

<form>
  <input [(ngModel)]="order.name" name="name">
  <input [(ngModel)]="order.count" name="count"> 
  <select-country [(ngModel)]="order.shippingCountry" name="shippingCountry"></select-country>
  <select-country [(ngModel)]="order.billingCountry" name="billingCountry"></select-country>
</form>

您可以像这样构建的组件:

import { Component, Input, forwardRef, Output, EventEmitter, OnInit } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

interface Country {
  value: string;
  countryName: string;
}

const SELECT_COUNTRY_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => SelectCountryComponent),
    multi: true,
};
@Component({
  selector: 'select-country',
  template: `
<div tabindex="-1">
  <select  [(ngModel)]="value" name="orderby" (ngModelChange)="updateValue($event)"> 
    <option *ngFor="let country of countries"  [selected]="country.value === value?.value" [value]="country.value">{{ country.countryName }}</option>
  </select>
</div>`,
  styles: [`:host { display: inline-block; }`],
  providers: [SELECT_COUNTRY_VALUE_ACCESSOR]
})
export class SelectCountryComponent implements ControlValueAccessor, OnInit {
  _value: Country;

  countries = []
  private onChangeCallback: Function;
  private onTouchedCallback: Function;

  constructor(private http: HttpClient) {}
  ngOnInit() {
    this.http.get('https://www.mocky.io/v2/5a90341e2f000061006caba7')
      .subscribe((countries: Country[]) => this.countries = countries,
      err => console.error('Error getting countries:', err));
  }
  /** that mock should return something like this:
   *     [{
           "countryName": "Ireland",
           "value": "IRELAND" // or whatever
    }, ...]
   */

  // update coming from external, e.g. form control
  writeValue(value) {
    // outside change of selected item
    console.log('Update value:', value);
    this._value = value;
  }

  // update coming from the view (our dropdown), we update it and then go on to inform Angular Forms.
  // called by the dropdown selector.
  updateValue(value) {
    this._value = this.countries.filter(country => country.value === value)[0];
    this.valueChange();
  }

  private valueChange() {
    this.onTouchedCallback();
    this.onChangeCallback(this._value);
  }

  // these two are set
  registerOnChange(onChangeCallback: Function) {
    this.onChangeCallback = onChangeCallback;
  }
  registerOnTouched(onTouchedCallback: any) {
    this.onTouchedCallback = onTouchedCallback;
  }
}

当然,请根据oyur需求进行调整,添加验证,样式等。您可以在此处看到它:https://stackblitz.com/edit/angular-country-picker?file=app/app.component.html

答案 1 :(得分:0)

除了我的其他答案(建议制作一个可以在其他地方重复使用的独立组件),让我们尝试更直接的方法,修复代码:

首先,您的模板options都缺少值。即使你的用户选择了某些东西,ngModel也不会改变(因为它总是相同的值,&#34;&#34;)。

<div tabindex="-1">
    <select  [(ngModel)]="shared.orderDetails.delivery_country" name="orderby"> 
      <option *ngFor="let item of items" [value]="item.countries_name">{{ item.countries_name }}</option>
    </select>
</div>

其次,你的init逻辑在构造函数中。在那种情况下,您仍然无法确定您的输入。将init部分移动到ngOnInit。     构造函数(公共http:Http,                 公共路由器:路由器,                 public configz:ConfigService,                 public shared:DataService,                 private checkOutservice:CheckOutService,                 私人服务:HomeService,                 公共材料:MdlService){     }

ngOnInit() {
  if(this.addressType === 'shipping') {
    this.va = shared.orderDetails.delivery_country
  } else {
    this.va = shared.orderDetails.billing_country;
  }
  const  data = { type: 'null' };
  http.post(this.configz.url + 'getCountries', data).map(res => res.json()).subscribe(data => {      
        this.items = this.countries = data.data;
        console.log(this.items);
        setTimeout(() => {  this.material.render(); }, 550);
  });
}