javascript - chart - title html
¿Cuál es la forma angular de enlazar datos con muchas entradas? (5)
Aquí hay una manera de hacerlo. Utilicé textareas y una estructura diferente para mis repetidores, pero el concepto principal es:
- mostrar un valor simple basado en el índice. (No unido)
- en borroso actualiza el modelo
- en la actualización de la versión del modelo
Esencialmente, fingir el enlace.
Violín de trabajo - http://jsfiddle.net/VvnWY/4/
El html:
<script type="text/ng-template" id="textareas.html">
<textarea ng-if="strings" ng-repeat="str in strings" ng-blur="blur( $event, $index )">{{strings[$index]}}</textarea>
</script>
<div ng-controller="MyCtrl">
Here''s a few strings: <br />
<div ng-repeat="str in strings">{{strings[$index]}}</div>
Here''s the strings as editable (twice so that you can see the updates from a model change): <br />
<form-textareas strings="strings"></form-textareas>
<form-textareas strings="strings"></form-textareas>
</div>
El JS:
var myApp = angular.module(''myApp'',[]);
angular.module(''myApp'', [])
.controller(''MyCtrl'', [''$scope'', function($scope) {
$scope.strings = [ "foo", "bar", "cow" ];
}])
.directive(''formTextareas'', function() {
return {
restrict: "E",
scope: {
strings: ''=''
},
templateUrl: "textareas.html",
link: function( $scope ){
$scope.blur = function( $event, $index ){
$scope.strings[ $index ] = $event.currentTarget.value;
};
}
};
})
;
Estoy aprendiendo angularjs y quiero permitir que el usuario ingrese muchas entradas. Cuando se ingresan estas entradas, los elementos de la matriz de list
deben cambiar en consecuencia. Quería probar el uso de la directiva ngRepeat pero leí que, dado que crea un nuevo ámbito, no puedo enlazar datos:
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item" type="text"/>
</div>
Me preguntaba si debería usar una directiva personalizada para hacer esto o abordarlo de manera diferente.
Considere usar la directiva ngList
https://docs.angularjs.org/api/ng/directive/ngList
Encontré una forma interesante de hacer esto, y me permite trabajar en una serie de primitivos.
Estoy usando AngularJS 1.2.1, que es la única versión en la que puedo hacer que funcione.
HTML:
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item" type="text" ng-blur="editItem($index, item)"/>
</div>
JavaScript:
$scope.editItem = function(idx, eItem) {
$scope.list[idx] = eItem;
};
Enlace: http://jsfiddle.net/bxD2P/10/ (gracias a Gloopy por el Fiddle inicial)
Estoy seguro de que hay formas fáciles de hacer agujeros en cómo funciona esto, y me encantaría escucharlos. Me permitiría apuntalar mi código.
La razón por la que el enlace de datos a un "elemento" primitivo no funciona es debido a la forma en que ng-repeat crea los ámbitos secundarios para cada elemento. Para cada elemento, ng-repeat tiene el nuevo alcance hijo prototípicamente heredado del alcance principal (ver líneas discontinuas en la imagen a continuación), y luego asigna el valor del elemento a una nueva propiedad en el ámbito hijo (elementos rojos en la imagen a continuación). El nombre de la nueva propiedad es el nombre de la variable de bucle. Desde el código fuente ng-repeat :
childScope = scope.$new();
...
childScope[valueIdent] = value;
Si el elemento es una primitiva, a la nueva propiedad de ámbito hijo se le asigna esencialmente una copia del valor de la primitiva. Esta propiedad de ámbito hijo no es visible para el ámbito principal, y los cambios que realice en el campo de entrada se almacenan en esta propiedad de ámbito hijo. Por ejemplo, supongamos que tenemos en el alcance principal
$scope.list = [ ''value 1'', ''value 2'', ''value 3'' ];
Y en el HTML:
<div ng-repeat="item in list">
Entonces, el primer ámbito hijo tendría la siguiente propiedad del item
, con un valor primitivo ( value 1
):
item: "value 1"
Debido a la vinculación de datos ng-model, los cambios que realice en el campo de entrada del formulario se almacenan en esa propiedad de ámbito hijo.
Puede verificar esto registrando el ámbito secundario en la consola. Agregue a su HTML, dentro de ng-repeat:
<a ng-click="showScope($event)">show scope</a>
Agregue a su controlador:
$scope.showScope = function(e) {
console.log(angular.element(e.srcElement).scope());
}
Con el enfoque de @ Gloopy, cada ámbito hijo todavía obtiene una nueva propiedad de "elemento", pero debido a que la lista ahora es una matriz de objetos, childScope[valueIdent] = value;
da como resultado que el valor de la propiedad del elemento se establezca como una referencia a uno de los objetos de la matriz (no una copia).
Al utilizar la técnica showScope (), verá que el valor de la propiedad del item
ámbito hijo hace referencia a uno de los objetos de la matriz: ya no es un valor primitivo.
Consulte también no enlazar con primitivas en ng-repeat ámbitos secundarios y
¿Cuáles son los matices del alcance de la herencia prototípica / prototípica en AngularJS? (que contiene imágenes de cómo se ven los ámbitos cuando se usa ng-repeat).
Tendrás mejor suerte si tu list
es una matriz de objetos (a diferencia de una serie de primitivos). Esto funciona bien aunque se cree un nuevo ámbito con ng-repeat
:
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item.value" type="text"/>
</div>
con un controlador de:
function TestController($scope) {
$scope.list = [ { value: ''value 1'' }, { value: ''value 2'' }, { value: ''value 3'' } ];
}
Vea este violín como un ejemplo.
Por otro lado, si intenta vincularse a una matriz de cadenas, el nuevo ámbito provocará un problema ya que los valores que está modificando no estarán vinculados a las primitivas de cadena de matriz original (como en este ejemplo de violín ).