2015-04-15 15 views
5

Chcę używać modelu ng z zewnętrzną usługą modelowania. Ten model ma dwie metody: getValue (zmienna) i setValue (zmienna).Angularne modele dynamiczne pobierające i modyfikujące model

Więc w moim html Chcę być w stanie to zrobić:

<input type="text" ng-model="balance"> 

Uwaga: bilans nie jest zdefiniowana na $ zakres w moim kontrolera. A ponieważ mamy do czynienia z ponad 4000 różnych zmiennych, nie chcę ich wszystkich definiować w $ scope.

A następnie po zmianie musi wywołać metodę setValue() modelu. Więc w moim kontrolera Chciałbym mieć coś takiego:

$catchAllGetter = function(variable) { // e.g. variable = 'balance' 
    var value = Model.getValue(variable); 
    return value; 
} 

$catchAllSetter = function(variable, value) { // called on change 
    Model.setValue(variable, value); 
} 

Czy coś jak to możliwe kątowe?

+0

Wystarczy popatrzeć na to http://jsfiddle.net/BDyAs/12/ – Reena

+0

Nie myśl, że to pomaga ... – Bob

Odpowiedz

3

Moje podejście jest podobne do @Dan Prince, ale realizacja różni się nieco

Tworzenie dyrektywa, która przyjmuje nazwę zmiennej modelu, a następnie wstrzyknąć model usługi w samej dyrektywie, aby wykonać pozyskiwanie i ustawienie.

Edit: Jak określono przez @Werlang, pisanie atrybut, który zastępuje ngModel powstrzyma cię od funkcji, takich jak zatwierdzanie, formatowanie debounced aktualizacji, NG-zmiany etc. Więc zamiast pisać zastępstwo, będziemy zamiast tego połącz dodatkowy atrybut:

.

app.directive('dynamicInput', function() { 
     return { 
     restrict: 'A', 
     link: function(scope, el, attr) { 
       scope.variableName = angular.copy(attr.ngModel); // Saving the variable name 

       scope[attr.ngModel] = (attr.ngModel + '_1'); // Setting a dummy value in the scope variable. 
       // In your case it will look something like scope[attr.ngModel] = Model.getValue(attr.ngModel); 

       scope.$watch(attr.ngModel, function(newValue, oldValue) { 

        console.log(scope.variableName + " ==> " + newValue); 

        //Model.setValue(scope.variableName, newValue); 

       }); 

     } 
     }; 
    }) 

Następnie w kodzie HTML:

<input ng-model='balance' dynamic-input /> 
+3

W ten sposób tracisz wszystkie funkcje wbudowane w model ng, takie jak sprawdzanie poprawności, formatowanie, aktualizacja debugowana, zmiana Ng, itp. –

+0

@ TechMa9iac dzięki za edycję, wygląda na ładne rozwiązanie! Spróbuję tego dzisiaj. –

1

Możesz utworzyć nową dyrektywę, która implementuje to zachowanie.

<input model-getter='getFn()' model-setter='setFn($value)' /> 

To byłoby dość proste do wdrożenia:

app.directive('modelGetter', function() { 
    return { 
    restrict: 'A', 
    scope: { 
     get: '&modelGetter', 
     set: '&modelSetter' 
    }, 
    link: function(scope, element) { 
     element.val(scope.get()); 
     element.on('change', function() { 
     var val = element.val(); 
     scope.set({ $value: val }); 
     }); 
    } 
    }; 
}) 
+2

ten sposób luźny cała funkcjonalność wbudowana w model ng, jak sprawdzanie poprawności, formatowanie, aktualizacja debugowana, zmiana ng, itp. –

1

spojrzenie na example, stworzyłem dla ciebie. Mam nadzieję, że zrozumiał poprawnie

$scope.$watch('variables', function(newValue) { 
    console.log("triggers on variables change"); 
    angular.forEach(newValue, function(value, key) { 
    Model.setValue(key, value); 
    }); 
}, true); 
0

mieć wszystkie swoje zmienne w tablicy obiektu:

[ 
    {key: "Variable 1", value: 1, kind: "number"}, 
    {key: "Variable 2", value: "some text", kind: "text"}, 
    {key: "Variable 3", value: new Date(), kind: "date"} 
] 

Następnie w widoku musi je utworzyć z pomocą w ng- powtórz:

<div ng-repeat="variable in myVariables"> 
    <input type="{{variable.kind}}" ng-model="variable.value" ng-change="changed(variable)"> 
</div> 

Jeśli y musisz zaktualizować swoją usługę zewnętrzną, zaimplementować zmienioną metodę (zmienną) w kontrolerze.

0

obsługuje programy pobierające i ustawiające.Oto jak to działa:

<input ng-model="balance" ng-model-options="{ getterSetter: true }"> 

To działa, jeśli balance jest funkcją getter/setter:

$scope.balance(100);  // sets 100 
var b = $scope.balance(); // returns 100 

Nie trzeba wystawiać każdą zmienną zakresu - można po prostu wystawiać usługi Model które można wykorzystać w swoim przykładzie:

$scope.Model = Model; 

następnie, w widoku, wiążą się cokolwiek nieruchomość trzeba:

<input ng-model="Model.balance" ng-model-options="{ getterSetter: true }"> 
0

ES5 właściwości obiektu na ratunek:

Object.defineProperty($scope, 'balance', { 
    enumberable: true, 
    get: function() { 
    // -- call your getter here 
    }, 
    set: function (val) { 
    // -- call the setter here 
    } 
}); 

Jest to rodzimy JavaScript, żeby nie dostać szybciej niż ten.

0

Możesz dynamicznie oceniać funkcję swojego modelu, np.

<input type="text" ng-model="myModel(var)"> 

iw sterowniku:

$scope.myModel = function(var) { 
    return function(newValue) { 
    // this is a regular model function but you can use 'var' here 
    ... 
    } 
}