3

Есть ли способ редактировать три разные переменные, используя только одну модель? Потому что в текущем подходе это выглядит так, как только переменное значение копируется в «editVar».Редактирование нескольких переменных с использованием одной модели

Fiddle of the code below

<div ng-controller="MyCtrl"> 
    A: {{A}}<br/> B: {{B}} <br/> C: {{C}}<br/> 
    <input ng-model="editedVar"/> 
    <br/> 
    <button ng-click="switchToA()">Switch to A</button> 
    <button ng-click="switchToB()">Switch to B</button> 
    <button ng-click="switchToC()">Switch to C</button> 
</div> 




var myApp = angular.module('myApp',[]); 

function MyCtrl($scope) { 
$scope.A = 1; 
$scope.B = 2; 
$scope.C = 3; 

    $scope.switchToA = function() 
    { 
     $scope.editedVar = $scope.A;  
    }; 

    $scope.switchToB = function() 
    { 
     $scope.editedVar = $scope.B;  
    }; 

    $scope.switchToC = function() 
    { 
     $scope.editedVar = $scope.C;  
    }; 
} 
+0

Что вы пытаетесь сделать? установите отредактированный Var на значение A, B или C? angular.copy не требуется для типов значений –

+0

Извините за эту копию, которую я просто забыл удалить, я просто удалил ее. Я пытаюсь изменить значения A B C, используя отредактированный вход VAR. Это возможно. Изменения на входе должны изменить значение A B или C, которое когда-либо было нажато. – SamSamet

+0

Не могли бы вы уточнить вопрос. Поэтому, чтобы быть понятным, вы хотите, чтобы кнопки устанавливали A, B & C в значение в editVar? Почему есть 3 кнопки, почему бы просто не использовать их? –

ответ

3

Вы можете сделать это во многих отношениях, вот простой и более Dry'ier способом.

View (Просто держать их просто только одна функция для изменения текущего редактируемого вар): -

<input ng-model="editedVar[editing]" /> 
<br /> 
<button ng-click="switchTo('A')">Switch to A</button> 
<button ng-click="switchTo('B')">Switch to B</button> 
<button ng-click="switchTo('C')">Switch to C</button> 

Контроллер: -

function MyCtrl($scope) { 
    /*Keep the values in an object with respective property name*/ 
    $scope.editedVar = { 
     A: 1, 
     B: 2, 
     C: 3 
    } 

    /*Set the default edit property*/ 
    $scope.editing = 'A'; 

    /*Sets the currently edited property based on what is being passed in*/  
    $scope.switchTo = function (prop) { 
     $scope.editing = prop; 
    }; 

} 

Fiddle

Вы также можете сделать но только с большим количеством кода обслуживания без использования объекта.

Вид: -

<input ng-model="editedVar" ng-change="valueChange()"/> 
<br/> 
<button ng-click="switchTo('A')">Switch to A</button> 
<button ng-click="switchTo('B')">Switch to B</button> 
<button ng-click="switchTo('C')">Switch to C</button> 

Контроллер: -

function MyCtrl($scope) { 

    $scope.A = 1; 
    $scope.B = 2; 
    $scope.C = 3; 

    var editing; 
    /*Change event to keep the value in sync*/ 
    $scope.valueChange = function(){ 
     $scope[editing] = $scope.editedVar; 
    } 
    /*Just one function*/ 
    $scope.switchTo = function (prop) { 
     $scope.editedVar = $scope[editing = prop]; 
    }; 

} 

Fiddle

+0

Это хорошо подходит для цели. Но есть ли способ получить эту работу без объектной структуры. просто передайте друг другу, как в моем примере? – SamSamet

+0

@SamSamet Да, вы могли бы, это не позволит вам держать вещи сухими, хотя и больше кода для поддержания состояния. Зачем вам это нужно? – PSL

+0

У меня есть таблица с сотнями строк, и когда щелкнут строка, я выхожу модальный для редактирования значений. Редактирующий модаль создается один раз, а затем мне нужен этот подход для назначения объекта строки, который будет редактироваться. – SamSamet

1

То, что вы хотите, это двусторонний связывание ссылки на не примитивного типа, смотрите ниже :

<div ng-controller="MyCtrl"> 
    A: {{A.val}}<br/> B: {{B.val}} <br/> C: {{C.val}}<br/> 
    <input ng-model="editedVar.val"/> 
    <br/> 
    <button ng-click="switchToA()">Swithc to A</button> 
    <button ng-click="switchToB()">Swithc to B</button> 
    <button ng-click="switchToC()">Swithc to C</button> 
</div> 



var myApp = angular.module('myApp',[]); 

function MyCtrl($scope) { 
    $scope.A = {val: 1}; 
    $scope.B = {val: 2}; 
    $scope.C = {val: 3}; 

    $scope.switchToA = function() 
    { 
     $scope.editedVar = $scope.A;  
    }; 

    $scope.switchToB = function() 
    { 
     $scope.editedVar = $scope.B;  
    }; 

    $scope.switchToC = function() 
    { 
     $scope.editedVar = $scope.C;  
    }; 
} 
+0

Скажите, есть ли у ОП 100 из этих свойств, ему нужно будет создать функцию 100, чтобы переключаться между ними, просто говоря? – PSL

+0

в этом случае, по-видимому, итерация массива практична. – elaijuh

+0

Да, или объект, который был бы намного проще (например, мой первый подход, вероятно), который был бы более явным, чем управление на основе индекса массива .. IMHO – PSL

1

Единственное ограничение ответа @ PSL заключается в том, что если другой код меняет значение A, B или C на объем, $scope.editedVar не обновляется корректно. Вместо этого, следующий альтернативный вариант использует два часовых механизма, чтобы гарантировать, что правильное свойство области поддерживается в актуальном состоянии, независимо от того, как вы его изменили, используя editedVar на входе или через какой-либо другой код.

Forked jsFiddle

var myApp = angular.module('myApp', []); 
 

 
myApp.controller('MyCtrl', function MyCtrl($scope) { 
 
    $scope.A = 1; 
 
    $scope.B = 2; 
 
    $scope.C = 3; 
 

 
    var propToEdit, 
 
    deregPrevWatch; 
 

 
    $scope.switchTo = function(prop) { 
 
    propToEdit = prop; 
 
    // set up a watch on this property so if anything else updates it 
 
    // editedVar gets correctly updated. 
 
    // Make sure to deregister the previous watch first. 
 
    if (deregPrevWatch) 
 
     deregPrevWatch(); 
 
    deregPrevWatch = $scope.$watch(prop, function(val) { 
 
     $scope.editedVar = val; 
 
    }); 
 
    }; 
 

 
    $scope.$watch('editedVar', function(newVal, oldVal) { 
 
    // skip the initialisation step 
 
    if (newVal !== oldVal) 
 
     $scope[propToEdit] = newVal; 
 
    }); 
 

 
    // start off pointing at A 
 
    $scope.switchTo('A'); 
 
});
p { 
 
    margin: 2px 0; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.7/angular.min.js"></script> 
 

 
<div ng-app="myApp"> 
 
    <div ng-controller="MyCtrl"> 
 
    <p>A: {{A}}</p> 
 
    <p>B: {{B}}</p> 
 
    <p>C: {{C}}</p> 
 
    <input ng-model="editedVar" /> 
 
    <p> 
 
     <button ng-click="switchTo('A')">Switch to A</button> 
 
     <button ng-click="switchTo('B')">Switch to B</button> 
 
     <button ng-click="switchTo('C')">Switch to C</button> 
 
     <button ng-click="A = 5">Set A to 5</button> 
 
    </p> 
 
    </div> 
 
</div>

+0

# 1 Я ненавижу создание часов, если это абсолютно необходимо. # 2 что вы подразумеваете под другим кодом, изменяющим значение A, B или C'. Вы имеете в виду динамическое изменение да, но на основании того, что OP сказал: «У меня есть таблица с сотнями строк и когда нажата строка Я поп чтобы изменить значения. «Я бы сказал, что это больше похоже на встроенную функцию редактирования, которая не нуждается в ней. Но это хорошее улучшение в моем первоначальном подходе, если это необходимо. – PSL

+0

# 1 Избегание создания часов, вероятно, является хорошим инстинктом в коде контроллера, но Angular создает для вас много часов. И я был осторожен, чтобы иметь только часы в любое время, отменив предыдущий. # 2 См. Пример моей кнопки, чтобы установить от A до 5. Если вы нажмете эту кнопку, когда «установите в A», вход должен обновиться, что будет работать, только если вы настроите часы на редактируемое свойство. – GregL

+0

Конечно, я знаю, что вы делаете, но, как я сказал, «если это абсолютно необходимо» ... Никогда не знайте, что OP original reqmnt может понадобиться в этом случае, это может быть другой лучший дизайн. – PSL

Смежные вопросы