Je suis bloqué sur la façon d'accéder à une valeur ngModel
et de la modifier à l'aide d'une directive. Le résultat du problème est que la valeur d'adresse du modèle ne se met pas à jour lorsque je sélectionne l'adresse souhaitée ... elle est simplement définie sur ce que j'ai réellement saisi dans l'entrée, plutôt que sur la valeur finale de l'entrée.
Je tape '830':
Je sélectionne '8300 Fauntleroy Way Southwest, Seattle, Washington, Etats-Unis':
Valeur résultante:
{
address: '830'
}
Valeur souhaitée:
{
address: '8300 Fauntleroy Way Southwest, Seattle, WA, United States'
}
Dans AngularJS, je pourrais faire ceci:
(function() {
'use strict';
angular
.module('casemanagerApp')
.directive('googleplace', googleplace);
function googleplace() {
var directive = {
require: 'ngModel',
link: link
};
return directive;
function link(scope, element, attrs, model) {
var options = {
types: [],
componentRestrictions: {}
};
scope.gPlace = new google.maps.places.Autocomplete(element[0], options); // jshint ignore:line
google.maps.event.addListener(scope.gPlace, 'place_changed', function() { // jshint ignore:line
scope.$apply(function() {
model.$setViewValue(element.val());
});
});
}
}
})();
Mais maintenant que j'essaye de le convertir Angular 2, je suis un peu coincé. Voici ce que j'ai jusqu'ici sur la conversion:
/// <reference path="../../../../typings/browser/ambient/googlemaps/index.d.ts"/>
import { Directive, ElementRef, OnInit } from '@angular/core';
@Directive({
selector: '[google-places]'
})
export class GooglePlaces implements OnInit {
constructor(private _el: ElementRef) { }
ngOnInit() {
let gPlace = new google.maps.places.Autocomplete(this._el.nativeElement);
google.maps.event.addListener(gPlace, 'place_changed', () => console.log(this._el.nativeElement));
}
}
Usage:
<input type="text"
ngControl="address"
placeholder="Enter a location"
[(ngModel)]="subject.address"
#address="ngForm"
google-places
required>
Le cœur du problème est que je ne comprends pas comment faire l'équivalent de model.$setViewValue(element.val());
dans Angular 2.
Toute assistance sera grandement appréciée.
J'ai fini par obtenir que cela fonctionne, bien que je ne comprenne pas pourquoi cela fonctionne parce que je ne lie pas ngModelChange
à l'élément ... mais cela fonctionne.
Directive:
/// <reference path="../../../../typings/browser/ambient/googlemaps/index.d.ts"/>
import { Directive, ElementRef, Output, EventEmitter, OnInit, NgZone } from '@angular/core';
@Directive({
selector: '[google-places]'
})
export class GooglePlaces implements OnInit {
@Output() ngModelChange: EventEmitter<any> = new EventEmitter(false);
options = {
types: ['address'],
componentRestrictions: { country: "us" }
};
constructor(
private _el: ElementRef,
private _ngZone: NgZone) { }
ngOnInit() {
let gPlace = new google.maps.places.Autocomplete(this._el.nativeElement, this.options);
google.maps.event.addListener(gPlace, 'place_changed', () => {
this._ngZone.run(() =>
this.ngModelChange.emit(this._el.nativeElement.value));
});
}
}
Modèle de composant:
<input type="text"
class="form-control"
ngControl="address"
id="subjectAddress"
placeholder="Enter a location"
[(ngModel)]="subject.address"
#address="ngForm"
google-places
required>
Je voudrais injecter la ControlValueAccessor
associée à votre entrée. Voici un échantillon:
@Directive({
selector: '[test]'
})
export class TestDirective {
constructor(@Inject(NG_VALUE_ACCESSOR) private valueAccessor:ControlValueAccessor) {
setTimeout(() => {
this.valueAccessor[0].writeValue('test');
}, 1000);
}
}
Voir cet exemple par exemple: https://plnkr.co/edit/owhBHdBncAxlzwJ8xkfq?p=preview .
C'est ce que j'ai fait avec mon datepicker, pourrait aider.
//Create a method in your component to change the model
dateChanged(date) {
this.hero.bday = date;
}
public ngOnInit() {
//CREATE A REFERERENCE TO YOUR COMPONENT
var component:CreateEventComponent = this;
$("#bday").datepicker({
dateFormat: "dd-mm-yy",
altFormat: "dd-mm-yy",
onSelect: function (dateText, datePicker) {
//UPDATE YOUR MODEL FORM JQUERY CODE.
component.dateChanged(dateText);
}
});
}