Estoy aprendiendo angular y estoy tratando de averiguar cuál es la mejor solución para el uso de los métodos getter/setter.

Diciendo, yo estoy usando una biblioteca que expone a los getters y setters (como Moment.js ¿).

He intentado de varias maneras para lidiar con getters y setters, aquí están:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example - example-ngModel-getter-setter-production</title>
<script data-require="[email protected]" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.18/angular.min.js">    </script>
<script src="app.js"></script>
</head>
<body ng-app="getterSetterExample">
<div ng-controller="ExampleController">
<form name="userForm">
Name :
<input type="text" name="userName" ng-model="user.name" ng-model-options="{ getterSetter: true }" />
<br/>Name1:
<input type="text" name="userName1" ng-model="user1.name" ng-model-options="{ getterSetter: true }" />
<br/>Name2:
<input type="text" name="userName2" ng-model="user2.name" ng-model-options="{ getterSetter: true }" />
<br/>Name3:
<input type="text" name="userName3" ng-model="user3.name" ng-model-options="{ getterSetter: true }" />
</form>
<pre>user.name =         <span ng-bind="user.name()"></span>
</pre>
<pre>user1.name =        <span ng-bind="user1.name()"></span>
</pre>
<pre>user2.name =        <span ng-bind="user2.name()"></span>
</pre>
<pre>user3.name =        <span ng-bind="user3.name()"></span>
</pre>
</div>
</body>
</html>

app.js

  angular.module('getterSetterExample', [])
.controller('ExampleController', ['$scope',
function($scope) {
var _name = 'Brian';
var _name3 = 'Joe';
var name1 = {
_name: 'George',
name:function(newName) {
if (angular.isDefined(newName)) {
this._name = newName;
}
return this._name;
}
};
var name2 = {
_name: 'Michael',
name:function(newName) {
if (angular.isDefined(newName)) {
this._name = newName;
}
return this._name;
}
};
var name3 = {
name:function(newName) {
if (angular.isDefined(newName)) {
_name3 = newName;
}
return _name3;
}
};
$scope.user = {
name: function(newName) {
if (angular.isDefined(newName)) {
_name = newName;
}
return _name;
}
};
$scope.user1 = {
name: name1.name
};
$scope.user2 = {
name: function(newName) {
return name2.name(newName);
}
};
$scope.user3 = {
name: name3.name
};
}
]);

Puedes probarlo aquí: http://plnkr.co/edit/S1qKre9umNpLOt0sjpZf?p=preview

2 Preguntas:

usuario1 intenta utilizar directamente la función de captador/definidor proporcionados por el nombre1 objet, no funciona correctamente, puede usted explicar por qué?

Hay una manera de evitar a escribir un «proxy» para cada uno de los métodos getter/setter como yo he hecho en el usuario3? ¿cuál sería el mejor método para utilizar los métodos getter/setter prestados por una biblioteca externa?

Gracias por su ayuda

InformationsquelleAutor Chris Dunom | 2014-08-22

1 Comentario

  1. 4

    usuario1 intenta utilizar directamente la función de captador/definidor proporcionados por el nombre1 objet, no funciona correctamente, puede usted explicar por qué?

    El problema es con el contexto, la mera copia de la referencia de la función name1.name haciendo:-

        $scope.user1 = {
    name: name1.name
    };

    por lo que cuando se ejecute this en el captador se apuntan a la window/global (no en modo estricto). Puede evitar este problema mediante el uso de La función.se unen.

    Ejemplo:-

        $scope.user1 = {
    name: name1.name.bind(name1)
    };

    Demo

    Hay una manera de evitar a escribir un «proxy» para cada uno de los métodos getter/setter como yo he hecho en el usuario3?

    Acabo de crear un contenedor para que no se quede en un contexto, con temas como estos.

        $scope.user = getModel('name', 'Brian');
    $scope.user1 = getModel('name', 'George');
    $scope.user2 = getModel('name', 'Michael');
    $scope.user3 = getModel('name', 'Joe');
    $scope.address = getModel('address');
    //You can improve this by passing an optional getter functionality as well for some specific evaluation on the value when set.
    function getModel(propertyName, defValue) {
    var obj =  {};
    obj._defVal = defValue;
    obj[propertyName] = function(newVal){
    if (angular.isDefined(newVal)) {
    obj[prop] = newVal;
    }
    return obj[prop];
    }
    return obj;
    }
    }

    O simplemente

     function getModel(propertyName, defValue) {
    var obj =  {};
    var propValue = defValue;
    obj[propertyName] = function(newVal){
    if (angular.isDefined(newVal)) {
    propValue = newVal;
    }
    return propValue;
    }
    return obj;
    }
    }

    Demo2

    • Gracias por tu útil y clara respuesta.
    • Tengo una preocupación con respecto al alcance.Usted señaló que el error fue el mal ámbito de aplicación durante la ejecución.He intentado modificar el código para incluir nombre2 en el ámbito de aplicación como esta: he sustituido var nombre2 por $scope.nombre2 y modificado index.html ng-model=»nombre2.nombre». Yo estaba esperando a arreglar el problema de ámbito por tener este encuadernada con el ámbito. ¿Dónde está el error?
    • «Usted ha señalado que el error fue el mal ámbito de aplicación durante la ejecución» en realidad No me refería contexto equivocado señalado por this. Yo no se lo que quieres decir. Se puede pegar el código en un plunker..
    • He editado el código aquí plnkr.co/editar/3dh1DmGvIy6V7YPPEfKV?p=vista previa (8º versión) – mira en la línea 20 en index.html y la línea 18 en app.js. Yo esperaba este ser enlazadas al $scope en tiempo de ejecución.
    • En realidad no.. Ver la línea de angular código if (ctrl.$options && ctrl.$options.getterSetter && isFunction(modelValue)) { modelValue = modelValue(); } Bascially la referencia de la función es modelValue y sólo es ejecutado sin un contexto. Es sólo la copia de referencia de la función que está siendo ejecutado. Este es siempre el problema cuando usamos this en el trozo de código donde no tenemos un control sobre el contexto de ejecución.
    • Gracias por la aclaración.

Dejar respuesta

Please enter your comment!
Please enter your name here