Tengo problemas para entender / usar los alcances para una interfaz de usuario modal angular.
Si bien no es evidente de inmediato aquí, tengo los módulos y todo configurado correctamente (por lo que puedo decir), pero estos ejemplos de código en particular son donde estoy encontrando el error.
index.html (la parte importante)
<div class="btn-group">
<button class="btn dropdown-toggle btn-mini" data-toggle="dropdown">
Actions
<span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right text-left">
<li><a ng-click="addSimpleGroup()">Add Simple</a></li>
<li><a ng-click="open()">Add Custom</a></li>
<li class="divider"></li>
<li><a ng-click="doBulkDelete()">Remove Selected</a></li>
</ul>
</div>
Controller.js (nuevamente, la parte importante)
MyApp.controller('AppListCtrl', function($scope, $modal){
$scope.name = 'New Name';
$scope.groupType = 'New Type';
$scope.open = function(){
var modalInstance = $modal.open({
templateUrl: 'partials/create.html',
controller: 'AppCreateCtrl'
});
modalInstance.result.then(function(response){
// outputs an object {name: 'Custom Name', groupType: 'Custom Type'}
// despite the user entering customized values
console.log('response', response);
// outputs "New Name", which is fine, makes sense to me.
console.log('name', $scope.name);
});
};
});
MyApp.controller('AppCreateCtrl', function($scope, $modalInstance){
$scope.name = 'Custom Name';
$scope.groupType = 'Custom Type';
$scope.ok = function(){
// outputs 'Custom Name' despite user entering "TEST 1"
console.log('create name', $scope.name);
// outputs 'Custom Type' despite user entering "TEST 2"
console.log('create type', $scope.groupType);
// outputs the $scope for AppCreateCtrl but name and groupType
// still show as "Custom Name" and "Custom Type"
// $scope.$id is "007"
console.log('scope', $scope);
// outputs what looks like the scope, but in this object the
// values for name and groupType are "TEST 1" and "TEST 2" as expected.
// this.$id is set to "009" so this != $scope
console.log('this', this);
// based on what modalInstance.result.then() is saying,
// the values that are in this object are the original $scope ones
// not the ones the user has just entered in the UI. no data binding?
$modalInstance.close({
name: $scope.name,
groupType: $scope.groupType
});
};
});
create.html (en su totalidad)
<div class="modal-header">
<button type="button" class="close" ng-click="cancel()">x</button>
<h3 id="myModalLabel">Add Template Group</h3>
</div>
<div class="modal-body">
<form>
<fieldset>
<label for="name">Group Name:</label>
<input type="text" name="name" ng-model="name" />
<label for="groupType">Group Type:</label>
<input type="text" name="groupType" ng-model="groupType" />
</fieldset>
</form>
</div>
<div class="modal-footer">
<button class="btn" ng-click="cancel()">Cancel</button>
<button class="btn btn-primary" ng-click="ok()">Add</button>
</div>
Entonces, mi pregunta es: ¿por qué el alcance no tiene un doble vínculo con la interfaz de usuario? y ¿por qué this
tiene los valores personalizados, pero $scope
no los tiene?
Intenté agregar ng-controller="AppCreateCtrl"
al cuerpo div en create.html, pero arrojó un error: "Proveedor desconocido: $ modalInstanceProvider <- $ modalInstance", así que no hubo suerte.
En este punto, mi única opción es devolver un objeto con this.name
y en this.groupType
lugar de usar $scope
, pero se siente mal.
Respuestas:
Conseguí que el mío funcione así:
var modalInstance = $modal.open({ templateUrl: 'partials/create.html', controller: 'AppCreateCtrl', scope: $scope // <-- I added this });
Sin nombre de formulario, no
$parent
. Estoy usando AngularUI Bootstrap versión 0.12.1.I fue advertido a esta solución por este .
fuente
Cuando se trata de ámbitos anidados, no vincule
<input>
s directamente a miembros del ámbito:<input ng-model="name" /> <!-- NO -->
Únelos al menos a un nivel más profundo:
<input ng-model="form.name" /> <!-- YES -->
La razón es que los ámbitos heredan prototípicamente su ámbito principal. Entonces, al configurar miembros de primer nivel, estos se establecen directamente en el ámbito secundario, sin afectar al principal. En contraste con eso, cuando se vincula a campos anidados (
form.name
), el miembroform
se lee desde el ámbito principal, por lo que al acceder a laname
propiedad se accede al objetivo correcto.Lea una descripción más detallada aquí .
fuente
controller as
sintaxis, no se encontrará con problemas de alcance anidado como estecontroller as
sintaxis?Actualización de noviembre de 2014 :
En realidad, su código debería funcionar después de actualizar a ui-bootstrap 0.12.0. Alcance transcluye se fusionó con el alcance del controlador de manera más necesidad de
$parent
oform.
cosas.Antes de la 0.12.0 :
El modal usa la transclusión para insertar su contenido. Gracias a
ngForm
que puedes controlar el alcance porname
atributo. Entonces, para escapar del alcance transcluido, simplemente modifique el formulario de esta manera:<form name="$parent">
o
<form name="$parent.myFormData">
Los datos del modelo estarán disponibles en el ámbito del controlador.
fuente
$modal
debería estar disponible para el controlador asignado al modal?scope:$scope
ingrese $ modal.open params map.$scope.open = function () { var modalInstance = $uibModal.open({ animation: $scope.animationsEnabled, templateUrl: 'myModalContent.html', controller: 'salespersonReportController', //size: size scope: $scope }); };
funciona para mí alcance: $ alcance gracias Jason Swett
fuente
Agrego alcance: $ alcance y luego funciona.
fuente