AngularJS-当使用ng模型时,输入文本框中的Value属性会被忽略吗?


218

如果我将简单的输入文本框值设置为类似于下面的“ bob”,则使用AngularJS。如果ng-model添加了属性,则该值不显示。

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

任何人都知道可以通过简单的方法将此输入默认设置为某值并保持ng-model?我尝试将a ng-bind与默认值一起使用,但这似乎也不起作用。

Answers:


223

这是理想的行为,您应该在控制器中而不是在视图中定义模型。

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


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

11
谢谢。但是在这种情况下,模型是在控制器中设置的。在Angular文档中,数据始终相同,数据是在控制器中设置的。但是我的控制器在JS文件中。在“编辑”表单上怎么办?如何将默认的表格数据传递给控制器​​“角度方式”?
ByScripts 2013年

8
这对我来说不起作用,但是添加Mark Rajcok(ng-init =“ rootFolders ='Bob'”)所示的附加属性ng-init效果很好。
Kaizar Laxmidhar 2014年

如果我有一个输入字段,例如:<input type =“ number” ng-model =“ newTransaction [$ index] [user.email]” />,如何设置默认值?
shish

188

Vojta描述了“角度方式”,但是如果您真的需要进行这项工作,@ 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”'部分。
Mark Rajcok

2
+1,但是,正如在链接讨论的其中一个帖子中所提到的那样,应避免使用它(因为从逻辑上讲它不太正确,并且使测试更加困难)。
0xc0de 2013年

1
如果在v1.2上也使用模型值,则此方法效果很好。<... ng-init =“ rootFolders = someModelAttribute” ...>
dmcqu314

@MarkRajcok,您在Stack Overflow上有很多很棒的AngularJS帖子!感谢您一直以来与SO社区分享见解的宝贵时间。当我说我们衷心感谢您为我们节省的所有时间时,我肯定会为许多感到欣慰的开发人员说话!
杰里米·莫里茨

1
真的很感谢Mark的回答,因为这解决了我的问题。我确实确认我们不需要value="Bob"输入标签中的一部分。
Devner,2014年

68

覆盖输入指令似乎确实可以完成任务。我对Dan Hunsaker的代码做了一些小的改动:

  • 尝试使用前添加了对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 2014年

这不仅是聪明的,也是最好的解决方案。就我而言,我无法在控制器上设置ng-model的默认值,因为它是PHP表单,如果服务器端验证失败,则该表单将刷新,并且ng-model中的所有内容都会丢失,删除输入值太。
Luis Elizondo 2014年

2
如果您还希望HTML表单的基本版本在没有JavaScript的情况下运行,则这似乎是最佳解决方案。
达伦(Darren)

出色的解决方案实际上应该是angular本身的非默认可配置选项。
格雷西2015年

感谢您的解决方案。您将如何解决数字输入问题?它引发错误docs.angularjs.org/error/ngModel/numfmt?p0=20.12
mate.gwozdz

21

角度方式

正确的Angular方法是在表单模板中编写一个单页应用程序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指令一起使用,或者根据需要绑定到$ scope以外的其他内容。

像这样使用它:

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

请注意,这也适用于textareas,然后选择下拉菜单。

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

@smoksnes-您完全正确。我已经更新了答案:)
superluminary

7

更新:我最初的答案是让控制器包含DOM感知代码,这打破了Angular约定,而支持HTML。@dmackerman在对我的答案的评论中提到了指令,直到现在我还是完全没想到。使用该输入,这是在不违反Angular 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属性视为Angular表达式(尽管我个人可能会为此使用不同的[custom]属性,因此标准HTML属性始终被视为常量)。

另外,在使模板化的数据可用于ng-model方面也存在类似的问题,这可能也很有趣。


您不应该在控制器中进行任何DOM操作/发现。应该改用指令。
dmackerman

2
我在回答中明确提到了这个缺点。你不应该,但是你可以。这取决于您是否发现遵循Angular或HTML的约定更重要。因为Angular确实会破坏HTML。
Dan Hunsaker 2013年

3
哦,我个假人。完全错过了有关使用指令的知识。答案已相应更新。真诚的道歉,@ dmackerman真是个混蛋。
Dan Hunsaker 2013年

感谢您的指示!它给了我一些想法,可以应用到我正在处理的项目中,在该项目中生成一些内容服务器端,然后必须将其用作客户端中的模型。
ggalmazor 2014年

很高兴我能帮助你。当然,通常来说,您希望将服务器端内容构建为JSON,并让您的应用基于该内容来操纵模型,但是有时使用其他选项很有用,但这只是一个选择。
Dan Hunsaker 2014年

7

如果使用AngularJs ngModel指令,请记住valueattribute 的值不绑定在ngModel字段上。您必须自己初始化它,而最好的方法是

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

在指令/标记而不是控制器中初始化它很奇怪。
random_user_name

5

这是对先前答案的略微修改。

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

请记住,ngModelController。$ setViewValue会将模型状态更改为dirty,将原始状态更改为false,这也会影响表单状态,这有时可能会很痛苦。
Atul Chaudhary

2

嗨,您可以尝试使用以下方法初始化模型。

在这里您可以两种方式初始化文本框的ng-model

-使用ng-init

-在JS中使用$ scope

<!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-model设置为要设置ng-value / value的父元素。如Angular所述:

它主要用于input [radio]和option元素,因此当选择元素时,该元素(或其选择父元素)的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>

注意:在上述情况下,我通常会对ng-model和值进行JSON响应,我只是向JS对象添加了另一个属性“ MarketPeers”。因此,模型和值可能会根据需要而定,但是我认为此过程会有所帮助,同时具有ng模型和值,但不要将它们放在同一元素上。


0

我有类似的问题。我无法value="something"用来显示和编辑。我必须<input>在声明的ng模型中使用以下命令。

[(ngModel)]=userDataToPass.pinCode

我在对象中具有数据列表的位置userDataToPass以及需要显示和编辑的项目是pinCode

同样,我提到了这个YouTube视频


对于这个HOWTO中,OP使用AngularJS,您YT视频参考使用角4
Chris22
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.