有两个地址发货和结算国家/地区。两者都有不同的价值。 组件在这里重复使用。 为此制定了一个精选国家组成部分。
<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>
如何动态更改ngModel并设置shared.orderDetails。 我只在共享中进行更改,因为有多个组件,他们需要共享相同的服务来保留数据。
编辑:我尝试在Get Country Component中设置变量。编辑它请检查。它不会更新shared.orederDetails。
答案 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);
});
}