AngularJS - Thuộc tính giá trị trên hộp văn bản đầu vào bị bỏ qua khi có mô hình ng được sử dụng?


218

Sử dụng AngularJS nếu tôi đặt giá trị hộp văn bản đầu vào đơn giản thành một cái gì đó như "bob" bên dưới. Giá trị không hiển thị nếu ng-modelthuộc tính được thêm vào.

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

Bất cứ ai cũng biết về một công việc đơn giản xung quanh để mặc định đầu vào này vào một cái gì đó và giữ nguyên ng-model? Tôi đã cố gắng sử dụng a ng-bindvới giá trị mặc định nhưng dường như cũng không hoạt động.

Câu trả lời:


223

Đó là hành vi mong muốn, bạn nên xác định mô hình trong bộ điều khiển, không phải trong khung nhìn.

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


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

11
Cảm ơn. Nhưng trong trường hợp này, mô hình được đặt trong bộ điều khiển. Và trong các tài liệu Angular, dữ liệu luôn được đặt trong bộ điều khiển. Nhưng bộ điều khiển của tôi nằm trong một tệp JS. Làm thế nào khi ở dạng "chỉnh sửa"? Làm thế nào để truyền dữ liệu biểu mẫu mặc định để điều khiển "cách góc"?
ByScripts

8
Điều này không hiệu quả với tôi tuy nhiên việc thêm thuộc tính ng-init được hiển thị bởi Mark Rajcok (ng-init = "rootFolders = 'Bob'") hoạt động tốt.
Kaizar Laxmidhar

Và làm cách nào để đặt giá trị mặc định nếu tôi có trường nhập như: <input type = "number" ng-model = "newTransaction [$ index] [user.email]" />?
shish

188

Vojta đã mô tả "cách góc", nhưng nếu bạn thực sự cần phải làm việc này, @urbanek gần đây đã đăng một cách giải quyết bằng cách sử dụng ng-init:

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

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


33
Bạn có thể không cần phần 'value = "Bob".
Đánh dấu Rajcok

2
+1 nhưng, như đã đề cập trong một trong các bài đăng trên cuộc thảo luận được liên kết, nên tránh (vì về mặt logic thì nó ít chính xác hơn và nó làm cho việc kiểm tra khó khăn hơn).
0xc0de

1
Phương pháp này hoạt động tốt nếu bạn sử dụng giá trị mô hình trên v1.2. <... ng-init = "rootFolders = someModelAttribution" ...>
dmcqu314

@MarkRajcok, bạn có rất nhiều bài đăng AngularJS tuyệt vời trên Stack Overflow! Cảm ơn bạn vì tất cả thời gian bạn đã dành để chia sẻ những hiểu biết của bạn với cộng đồng SO. Tôi chắc chắn rằng tôi nói cho nhiều nhà phát triển nhẹ nhõm khi tôi nói rằng chúng tôi chân thành đánh giá cao tất cả những giờ bạn đã cứu chúng tôi!
Jeremy Moritz

1
Thực sự đánh giá cao câu trả lời của Mark vì điều đó đã giải quyết vấn đề của tôi. Tôi xác nhận rằng chúng tôi KHÔNG cần value="Bob"một phần trong thẻ đầu vào.
Devner

68

Ghi đè chỉ thị đầu vào dường như thực hiện công việc. Tôi đã thực hiện một số thay đổi nhỏ đối với mã của Dan Hunsaker :

  • Đã thêm kiểm tra cho ngModel trước khi thử sử dụng $parse().assign()trên các trường không có thuộc tính ngModel.
  • Sửa lỗi assign()thứ tự hàm param.
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);
      }
    }
  };
});

Đây là câu trả lời tốt nhất tôi tìm thấy! ... giải quyết vấn đề của tôi một cách tao nhã. Tôi đã phải nắm bắt một giá trị trên một đầu vào ẩn (mã thông báo dạng Symfony, được tạo trong máy chủ).
PachinSV

Đây không chỉ là thông minh mà là giải pháp tốt nhất. Trong trường hợp của tôi, tôi không thể đặt giá trị mặc định của mô hình ng trên bộ điều khiển vì là dạng PHP, nếu xác thực phía máy chủ không thành công, biểu mẫu sẽ làm mới và bất cứ điều gì trong mô hình ng sẽ bị mất khi xóa giá trị đầu vào quá.
Luis Elizondo

2
Đây có vẻ là giải pháp tốt nhất nếu bạn cũng muốn một phiên bản cơ bản của biểu mẫu HTML của mình hoạt động mà không cần JavaScript.
Darren

Giải pháp tuyệt vời thực sự nên là một tùy chọn cấu hình không mặc định trong chính góc.
Gracie

Cảm ơn giải pháp của bạn. Làm thế nào bạn sẽ giải quyết vấn đề đầu vào số? Nó ném một lỗi docs.angularjs.org/error/ngModel/numfmt?p0=20.12
mate.gwozdz

21

Cách góc

Cách Angular chính xác để làm điều này là viết một ứng dụng trang duy nhất, AJAX trong mẫu biểu mẫu, sau đó điền nó một cách linh hoạt từ mô hình. Mô hình không được điền từ biểu mẫu theo mặc định vì mô hình là nguồn duy nhất. Thay vào đó, Angular sẽ đi theo con đường khác và cố gắng điền vào mẫu từ mô hình.

Tuy nhiên, nếu bạn không có thời gian để bắt đầu lại từ đầu

Nếu bạn có một ứng dụng được viết, điều này có thể liên quan đến một số thay đổi kiến ​​trúc khá nặng. Nếu bạn đang cố gắng sử dụng Angular để cải thiện một biểu mẫu hiện có, thay vì xây dựng toàn bộ ứng dụng một trang từ đầu, bạn có thể lấy giá trị từ biểu mẫu và lưu trữ trong phạm vi tại thời điểm liên kết bằng cách sử dụng một lệnh. Angular sau đó sẽ liên kết giá trị trong phạm vi trở lại biểu mẫu và giữ cho nó đồng bộ.

Sử dụng một chỉ thị

Bạn có thể sử dụng một lệnh tương đối đơn giản để kéo giá trị từ biểu mẫu và tải nó vào phạm vi hiện tại. Ở đây tôi đã định nghĩa một lệnh 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);
      }
    };
  });

Bạn có thể thấy tôi đã xác định một vài dự phòng để có được một tên mô hình. Bạn có thể sử dụng lệnh này kết hợp với chỉ thị ngModel hoặc liên kết với thứ gì đó ngoài phạm vi $ nếu bạn thích.

Sử dụng nó như thế này:

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

Lưu ý điều này cũng sẽ hoạt động với textareas và chọn thả xuống.

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

Đây là một mô-đun đóng gói thực hiện một giải pháp tương tự như mô tả ở đây github.com/platanus/angular-keep-values
Agustin

1
Giải pháp tuyệt vời, nhưng nó sẽ chỉ làm việc với input="text". Nếu bạn có numbernó, nó sẽ ném Model không phải là loại number docs.angularjs.org/error/ngModel/numfmt?p0=333
smoksnes

2
Để hỗ trợ các số bạn có thể thêm if (attrs.type === "number") val = parseInt(val);
smoksnes

@smoksnes - bạn hoàn toàn chính xác. Tôi đã cập nhật câu trả lời :)
superluminary

7

Cập nhật: Câu trả lời ban đầu của tôi liên quan đến việc bộ điều khiển có chứa mã nhận biết DOM, phá vỡ các quy ước Angular có lợi cho HTML. @dmackerman đã đề cập đến các chỉ thị trong một nhận xét về câu trả lời của tôi và tôi hoàn toàn bỏ lỡ điều đó cho đến tận bây giờ. Với đầu vào đó, đây là cách đúng đắn để làm điều này mà không vi phạm các quy ước Angular hoặc HTML:


Cũng có một cách để có được cả hai - lấy giá trị của phần tử và sử dụng nó để cập nhật mô hình theo chỉ thị:

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

và sau đó:

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);
            }
        }
    };
}]);

Tất nhiên, bạn có thể sửa đổi chỉ thị trên để làm nhiều hơn với valuethuộc tính trước khi đặt mô hình thành giá trị của nó, bao gồm cả việc sử dụng $parse(attrs.value, scope)để coi valuethuộc tính là biểu thức Angular (mặc dù tôi có thể sử dụng thuộc tính [tùy chỉnh] khác cho điều đó, cá nhân, vì vậy các thuộc tính HTML tiêu chuẩn luôn được coi là hằng số).

Ngoài ra, có một câu hỏi tương tự tại Làm dữ liệu được tạo sẵn cho mô hình ng cũng có thể được quan tâm.


Bạn không nên thực hiện bất kỳ thao tác / khám phá DOM nào trong bộ điều khiển của mình. Nên sử dụng một chỉ thị thay thế.
dmackerman

2
Tôi đã đề cập rõ ràng nhược điểm đó trong câu trả lời của tôi. Bạn không nên , nhưng bạn có thể . Tất cả phụ thuộc vào việc bạn thấy điều quan trọng hơn là tuân theo các quy ước của Angular hay HTML. Bởi vì Angular phá vỡ HTML.
Dan Hunsaker

3
Ồ, tôi một hình nộm. Hoàn toàn bỏ lỡ một chút về việc sử dụng một lệnh. Trả lời cập nhật cho phù hợp. Xin lỗi chân thành vì đã là một thằng ngốc với bạn, @dmackerman.
Dan Hunsaker

Cảm ơn chỉ thị! Nó đã cho tôi ý tưởng để áp dụng trong một dự án tôi đang làm việc ở đó tôi tạo ra một số máy chủ nội dung và sau đó phải sử dụng nó làm mô hình của mình trong máy khách.
ggalmazor

Rất vui vì tôi có thể giúp. Tất nhiên, nói chung, bạn sẽ muốn xây dựng nội dung phía máy chủ của mình dưới dạng JSON và ứng dụng của bạn điều khiển mô hình dựa trên điều đó, nhưng đôi khi thật hữu ích khi có các tùy chọn khác, và đây chỉ là một.
Dan Hunsaker

7

Nếu bạn sử dụng chỉ thị ngModel của AngularJs, hãy nhớ rằng giá trị của valuethuộc tính không liên kết trên trường ngModel . Bạn phải tự khởi tạo nó và cách tốt nhất để làm điều đó là

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

Cảm thấy kỳ lạ khi khởi tạo nó trong chỉ thị / đánh dấu thay vì bộ điều khiển.
Random_user_name

5

Đây là một sửa đổi nhỏ cho các câu trả lời trước đó ...

Không cần $ parse

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;
}]);

Hãy nhớ rằng ngModelControll. $ setViewValue sẽ thay đổi trạng thái mô hình thành bẩn và nguyên sơ thành sai, điều này cũng sẽ ảnh hưởng đến trạng thái biểu mẫu có thể bị đau một lúc nào đó.
Atul Chaudhary

2

Xin chào, bạn có thể thử các phương pháp dưới đây với khởi tạo mô hình.

Tại đây bạn có thể khởi tạo mô hình ng của hộp văn bản theo hai cách

- Với việc sử dụng ng-init

- Với việc sử dụng phạm vi $ trong 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

Vấn đề là bạn phải đặt mô hình ng thành phần tử cha thành nơi bạn muốn đặt ng-value / value. Như được đề cập bởi Angular:

Nó chủ yếu được sử dụng trên các phần tử đầu vào [radio] và tùy chọn, để khi phần tử được chọn, ngModel của phần tử đó (hoặc phần tử cha được chọn của nó) được đặt thành giá trị ràng buộc.

Ví dụ: Đây là một mã được thực thi:

<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>

Lưu ý: Trong trường hợp trên, tôi đã có phản hồi JSON cho mô hình ng và giá trị, tôi chỉ thêm một thuộc tính khác vào đối tượng JS là "MarketPeer". Vì vậy, mô hình và giá trị có thể phụ thuộc vào nhu cầu, nhưng tôi nghĩ rằng quá trình này sẽ giúp, để có cả mô hình ng và giá trị nhưng không có chúng trên cùng một yếu tố.


0

Tôi đã có vấn đề tương tự. Tôi không thể sử dụng value="something"để hiển thị và chỉnh sửa. Tôi đã phải sử dụng lệnh dưới đây bên trong <input>mô hình cùng với việc được khai báo.

[(ngModel)]=userDataToPass.pinCode

Nơi tôi có danh sách dữ liệu trong đối tượng userDataToPassvà mục mà tôi cần hiển thị và chỉnh sửa là pinCode.

Tương tự, tôi đã đề cập đến video YouTube này


Đối với cách này, OP đang sử dụng AngularJS, tham chiếu video YT của bạn đang sử dụng Angular 4.
Chris22 17/07/19
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.