AngularJS - атрибут значення у текстовому полі введення ігнорується, коли використовується ng-модель?


219

Використовуючи AngularJS, якщо я встановив просте значення текстового поля для введення на щось на зразок "bob" нижче. Значення не відображається, якщо ng-modelатрибут додано.

    <input type="text"
           id="rootFolder"
           ng-model="rootFolders"
           disabled="disabled"
           value="Bob"
           size="40"/>

Хто-небудь знає про просту роботу, щоб дефолтувати цей вклад на щось і зберегти ng-model? Я намагався використовувати значення ng-bindзі значенням за замовчуванням, але це, здається, не працює.

Відповіді:


223

Це бажана поведінка, вам слід визначити модель в контролері, а не в перегляді.

<div ng-controller="Main">
  <input type="text" ng-model="rootFolders">
</div>


function Main($scope) {
  $scope.rootFolders = 'bob';
}

11
Дякую. Але в цьому випадку модель встановлюється в контролері. А в кутових документах завжди те саме, дані задаються в контролері. Але мій контролер знаходиться у файлі JS. Як це зробити, коли на формі "редагувати"? Як передати дані форми за замовчуванням до контролера "кутовим шляхом"?
ByScripts

8
Для мене це не працює, проте додавання додаткового атрибута ng-init, показаного Марком Райкоком (ng-init = "rootFolders = 'Bob"), працює чудово.
Kaizar Laxmidhar

І як мені встановити значення за замовчуванням, якщо у мене є поле введення типу: <input type = "number" ng-model = "newTransaction [$ index] [user.email]" />?
shish

188

Войта описав "кутовий шлях", але якщо вам справді потрібно зробити цю роботу, @urbanek нещодавно опублікував вирішення за допомогою ng-init:

<input type="text" ng-model="rootFolders" ng-init="rootFolders='Bob'" value="Bob">

https://groups.google.com/d/msg/angular/Hn3eztNHFXw/wk3HyOl9fhcJ


33
Можливо, вам не знадобиться частина 'value = "Bob"'.
Марк Райкок

2
+1, але, як зазначалося в одному з дописів пов'язаної дискусії, цього слід уникати (як логічно, це менш правильно і це робить тестування складніше).
0xc0de

1
Цей метод працює добре, якщо ви використовуєте значення моделі також на v1.2. <... ng-init = "rootFolders = someModelAttribute" ...>
dmcqu314

@MarkRajcok, у вас стільки чудових публікацій AngularJS на стеку Overflow! Дякуємо вам за весь час, який ви присвятили діленню своєї думки із спільнотою SO. Я впевнений, що я розмовляю за багатьох розробників з полегшенням, коли кажу, що ми щиро цінуємо всі години, які ви врятували!
Джеремі Моріц

1
Дуже ціную відповідь Марка, як це вирішило моє питання. Я дійсно підтверджую, що нам НЕ потрібно value="Bob"участь у тезі введення.
Devner

68

Переосмислення вхідної директиви, здається, виконує цю роботу. Я вніс деякі незначні зміни до коду Дена Хансакера :

  • Додано чек на ngModel перед тим, як спробувати використовувати $parse().assign()на полях без атрибутів ngModel.
  • Виправлено порядок assign()функції парам.
app.directive('input', function ($parse) {
  return {
    restrict: 'E',
    require: '?ngModel',
    link: function (scope, element, attrs) {
      if (attrs.ngModel && attrs.value) {
        $parse(attrs.ngModel).assign(scope, attrs.value);
      }
    }
  };
});

Це найкраща відповідь, яку я знайшов! ... вирішує мою проблему елегантно. Мені довелося фіксувати значення на прихованому вході (маркер форми Symfony, згенерований на сервері).
PachinSV

Це не тільки розумне, але найкраще рішення. У моєму випадку я не можу встановити на контролері значення ng-моделі за замовчуванням, оскільки це форма PHP, якщо перевірка на стороні сервера не вдасться, форма оновиться, і все, що є в ng-моделі, втрачається, видаляючи вхідне значення теж.
Луїс Елізондо

2
Це здається найкращим рішенням, якщо ви також хочете, щоб основна версія вашої HTML форми працювала без JavaScript.
Даррен

Відмінне рішення, яке дійсно повинно бути не налаштованим за замовчуванням параметром у межах самого кута.
Грейсі

Дякуємо за ваше рішення. Як би ви вирішили питання введення числа? Він видає помилку docs.angularjs.org/error/ngModel/numfmt?p0=20.12
mate.gwozdz

21

Кутовий шлях

Правильний кутовий спосіб зробити це - написати додаток на одній сторінці, AJAX у шаблон форми, а потім динамічно заповнити його у моделі. Модель не заповнюється із форми за замовчуванням, оскільки модель є єдиним джерелом істини. Натомість Angular піде іншим шляхом і спробує заповнити форму з моделі.

Якщо, однак, у вас немає часу починати з нуля

Якщо у вас є додаток, написане, це може спричинити за собою досить значні архітектурні зміни. Якщо ви намагаєтеся використовувати Angular для вдосконалення існуючої форми, а не для того, щоб створювати з однієї сторінки цілу програму для однієї сторінки, ви можете витягнути значення з форми та зберегти її у межах в часі посилання за допомогою директиви. Потім Angular буде прив'язувати значення в області назад до форми і зберігати його в синхронізації.

Використання директиви

Ви можете використовувати відносно просту директиву, щоб витягнути значення з форми і завантажити її в поточну область. Тут я визначив директиву initFromForm.

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

angular.module('initFromForm', [])
  .directive("initFromForm", function ($parse) {
    return {
      link: function (scope, element, attrs) {
        var attr = attrs.initFromForm || attrs.ngModel || element.attrs('name'),
        val = attrs.value;
        if (attrs.type === "number") {val = parseInt(val)}
        $parse(attr).assign(scope, val);
      }
    };
  });

Ви можете бачити, що я визначив пару резервних копій, щоб отримати назву моделі. Ви можете використовувати цю директиву спільно з директивою ngModel або прив'язувати до чогось іншого, ніж $ range, якщо вам зручніше.

Використовуйте його так:

<input name="test" ng-model="toaster.test" value="hello" init-from-form />
{{toaster.test}}

Зверніть увагу, це також буде працювати з текстовими областями та вибирати спадні місця.

<textarea name="test" ng-model="toaster.test" init-from-form>hello</textarea>
{{toaster.test}}

Ось упакований модуль, який реалізує рішення, подібне до описаного тут github.com/platanus/angular-keep-values
Agustin

1
Прекрасне рішення, але воно буде працювати лише з цим input="text". Якщо у вас numberце буде, викинете модель не типу number docs.angularjs.org/error/ngModel/numfmt?p0=333
smoksnes

2
Для підтримки номерів ви можете додати if (attrs.type === "number") val = parseInt(val);
smoksnes

@smoksnes - ви абсолютно праві. Я оновив відповідь :)
superluminary

7

Оновлення: в моїй оригінальній відповіді пов'язано те, що контролер містить код DOM, який порушує кутові умови на користь HTML. @dmackerman згадав директиви у коментарі до моєї відповіді, і я зовсім пропустив це досі. З цим вводом ось правильний спосіб зробити це, не порушуючи кутових або HTML-умов:


Існує також спосіб отримати і те й інше - захопити значення елемента і використовувати його для оновлення моделі в директиві:

<div ng-controller="Main">
    <input type="text" id="rootFolder" ng-model="rootFolders" disabled="disabled" value="Bob" size="40" />
</div>

і потім:

app.directive('input', ['$parse', function ($parse) {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function (scope, element, attrs) {
            if(attrs.value) {
                $parse(attrs.ngModel).assign(scope, attrs.value);
            }
        }
    };
}]);

Ви, звичайно, можете змінити вищевказану директиву, щоб зробити більше з valueатрибутом перед тим, як встановити модель на її значення, включаючи використання $parse(attrs.value, scope)для лікуванняvalue атрибута як кутового виразу (хоча, мабуть, я використовував би інший [користувальницький] атрибут для цього особисто, тому стандартні атрибути HTML послідовно трактуються як константи).

Також є подібне питання щодо створення шаблонів даних у доступній для ng-моделі, що також може представляти інтерес.


Ви не повинні робити жодних маніпуляцій / виявлення DOM у своїх контролерах. Слід використовувати директиву замість цього.
dmackerman

2
Я чітко згадував про цей недолік у своїй відповіді. Ви не повинні , але можете . Все залежить від того, чи вважаєте ви важливішим слідувати умовам Angular або HTML. Тому що Angular дійсно зламає HTML.
Dan Hunsaker

3
О, я є фіктивним. Повністю пропустив біт щодо використання директиви. Відповідь оновлена ​​відповідно. Найщиріші вибачення за те, що вам пришпилено, @dmackerman.
Dan Hunsaker

Дякую за директиву! Це дало мені ідеї застосувати проект, над яким я працюю, де я генерую деяку сторону сервера вмісту, а потім мушу використовувати його як свою модель у клієнті.
ggalmazor

Радий, що можу допомогти. Звичайно, загалом кажучи, ви хочете створити контент на стороні сервера як JSON і змусити ваш додаток маніпулювати моделлю на основі цього, але іноді корисно мати інші варіанти, і це лише один.
Dan Hunsaker

7

Якщо ви використовуєте директиву AngularJs ngModel, пам’ятайте, що значення valueатрибута не пов'язується з полем ngModel. Ви повинні його запустити самостійно, і найкращий спосіб це зробити - це

<input type="text"
       id="rootFolder"
       ng-init="rootFolders = 'Bob'"
       ng-model="rootFolders"
       disabled="disabled"
       value="Bob"
       size="40"/>

Думає, що не вводити його в директиву / розмітку замість контролера.
random_user_name

5

Це незначна зміна попередніх відповідей ...

Немає потреби в розборі $

angular.directive('input', [function () {
  'use strict';

  var directiveDefinitionObject = {
    restrict: 'E',
    require: '?ngModel',
    link: function postLink(scope, iElement, iAttrs, ngModelController) {
      if (iAttrs.value && ngModelController) {
        ngModelController.$setViewValue(iAttrs.value);
      }
    }
  };

  return directiveDefinitionObject;
}]);

майте на увазі, що ngModelController. $ setViewValue змінить стан моделі на брудний і незайманий на хибний, що також вплине на форму форми, яка може боліти деякий час.
Атул Чадхарі

2

Привіт, ви можете спробувати нижче методи з ініціалізацією моделі.

Тут ви можете ініціалізувати ng-модель текстового поля двосторонньо

- З використанням ng-init

- З використанням $ range в js

<!doctype html>
 <html >
 <head>
        <title>Angular js initalize with ng-init and scope</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
</head>
<body ng-app="app" >
    <h3>Initialize value with ng-init</h3>
    <!-- Initlialize model values with ng-init -->
    <div ng-init="user={fullname:'Bhaskar Bhatt',email:'bhatt.bhaskar88@gmail.com',address:'Ahmedabad'};">
        Name : <input type="text" ng-model="user.fullname" /><br/>
        Email : <input type="text" ng-model="user.email" /><br/>
        Address:<input type="text" ng-model="user.address" /><br/>

    </div>  
    <!-- initialize with js controller scope -->
    <h3>Initialize with js controller</h3>

    <div  ng-controller="alpha">
        Age:<input type="text" name="age" ng-model="user.age" /><br/>
        Experience : <input type="text" name="experience" ng-model="user.exp" /><br/>
        Skills : <input type="text" name="skills" ng-model="user.skills" /><br/>
    </div>  

</body> 
<script type="text/javascript">
        angular.module("app",[])
        .controller("alpha",function($scope){
            $scope.user={};
            $scope.user.age=27;
            $scope.user.exp="4+ years";
            $scope.user.skills="Php,javascript,Jquery,Ajax,Mysql";
        });

     </script>
 </html>                

0

Проблема полягає в тому, що ви повинні встановити ng-модель для батьківського елемента, куди ви хочете встановити ng-значення / значення. Як згадував Angular:

В основному він використовується на вхідних [радіо] та елементах параметрів, так що коли елемент вибраний, ngModel цього елемента (або його батьківського елемента вибору) встановлюється на прив’язане значення.

Наприклад: Це виконаний код:

<div class="col-xs-12 select-checkbox" >
<label style="width: 18em;" ng-model="vm.settingsObj.MarketPeers">
  <input name="radioClick" type="radio"  ng-click="vm.setPeerGrp('market');" 
         ng-value="vm.settingsObj.MarketPeers" 
         style="position:absolute;margin-left: 9px;">
  <div style="margin-left: 35px;color: #717171e8;border-bottom: 0.5px solid #e2e2e2;padding-bottom: 2%;">Hello World</div>
</label>
</div>

Примітка. У цьому вище випадку я отримав відповідь JSON на ng-модель та значення, я просто додаю ще одне властивість до об'єкта JS як "MarketPeers". Тож модель і значення можуть залежати від потреби, але я думаю, що цей процес допоможе мати ng-модель і значення, але не мати їх на одному елементі.


0

У мене було подібне питання. Мені не вдалося використовувати value="something"для відображення та редагування. Мені довелося використовувати нижченаведену команду всередині моєї <input>заявленої моделі.

[(ngModel)]=userDataToPass.pinCode

Там, де у мене є перелік даних в об’єкті, userDataToPassі елемент, який мені потрібно відобразити та редагувати, - цеpinCode .

Для цього я згадував це відео на YouTube


Для цього якTo, OP використовує AngularJS, ваш YT відео посилання використовує Angular 4.
Chris22
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.