将自定义指令动态绑定到ng-repeat(Dynamically binding custom directive to ng-repeat)
我的控制器有我的表单的json然后我有一个指令,重复生成表单元素。 基于传递给指令的'type',指令应该知道如何呈现元素。
但我不知道为什么它不能正确渲染表单模板,但这是一个单独的问题。
我的直接问题是,我无法看到传递ng模型并将其正确绑定到模板。
有谁看到我的问题?
var myApp = angular.module('myApp', []); myApp.directive('ioProductElement', ['$compile', function ($compile) { var dropdownTemplate = '<select ng-model="model" ng-options="option.Text for option in data"></select>'; var textAreaTemplate = '<textarea ng-model="model" class="form-control">{{ data }}</textarea>'; var radioListTemplate = '<span ng-repeat="item in data.Items"><input ng-model="model" type="radio" name="{{ data.Name }}" ng-checked="item.Selected" /><label>{{ item.ProductLabel }}</label> </span>'; return { restrict: 'E', replace: true, scope: { model: '=', type: '=', data: '=' }, link: function (scope, element) { var getTemplate = function (type) { var template = ''; switch (type) { case 'SelectListItem': template = dropdownTemplate; scope.model = _.find(scope.data, { Selected: true }); break; case 'TextArea': template = textAreaTemplate; break; case 'RadioList': template = radioListTemplate; break; } return template; }; element.html(getTemplate(scope.type)); $compile(element.contents())(scope); } }; }]); myApp.controller('DynamicFormController', function () { this.productElement = {}; this.product = { ProductName: 'Online Form', Company: 'TEST', Data: [] }; this.productItems = [{ ProductLabel: "Status", ProductType: "SelectListItem", ProductData: [{ "Text": "Item1", "Value": "1", Selected: true }, { "Text": "Item2", "Value": "2" }] }, { ProductLabel: "Publication", ProductType: "SelectListItem", ProductData: [{ Text: 'Item1', Value: '1' }, { Text: 'Item2', Value: '2', Selected: true }] }, { ProductLabel: "Caption", ProductType: "TextArea", ProductData: "this is some data for the textarea" }, { ProductLabel: "Display Advertising", ProductType: "RadioList", ProductData: { Name: "classifiedAdvertising", Items: [{ Text: 'Full Page', Selected: true }, { Text: '1/2 Page' }] } }, { ProductLabel: "Status2", ProductType: "SelectListItem", ProductData: [{ "Text": "Item1", "Value": "1" }, { "Text": "Item2", "Value": "2" }, { "Text": "Item3", "Value": "3", Selected: true }] }, ]; this.save = function () { this.product.Data = this.productItems; console.log('in save', this.product); }; });<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.4.0/lodash.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> <div class="col-sm-12" ng-app="myApp"> <br /> <form class="form-horizontal" ng-controller="DynamicFormController as ctrl"> <div class="form-group" ng-repeat="item in ctrl.productItems"> <label class="col-sm-2 control-label">{{ item.ProductLabel }}</label> <div class="col-sm-10"> <io-product-element data-model="ctrl.productElement[item.ProductLabel]" data-type="item.ProductType" data-data="item.ProductData"></io-product-element> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="button" class="btn btn-info" data-ng-click="ctrl.save()" value="Submit" /> product: {{ ctrl.product | json }} </div> </div> </form> </div>my controller has the json for my form then i have a directive that gets repeated to produce the form elements. based on the 'type' passed to the directive, the directive should know how to render the element.
but i don't know why it's not rendering the form templates properly here but that's a separate issue.
my immediate issue is, i can't seen to pass the ng-model and bind it correctly to the template.
does anyone see my problem?
var myApp = angular.module('myApp', []); myApp.directive('ioProductElement', ['$compile', function ($compile) { var dropdownTemplate = '<select ng-model="model" ng-options="option.Text for option in data"></select>'; var textAreaTemplate = '<textarea ng-model="model" class="form-control">{{ data }}</textarea>'; var radioListTemplate = '<span ng-repeat="item in data.Items"><input ng-model="model" type="radio" name="{{ data.Name }}" ng-checked="item.Selected" /><label>{{ item.ProductLabel }}</label> </span>'; return { restrict: 'E', replace: true, scope: { model: '=', type: '=', data: '=' }, link: function (scope, element) { var getTemplate = function (type) { var template = ''; switch (type) { case 'SelectListItem': template = dropdownTemplate; scope.model = _.find(scope.data, { Selected: true }); break; case 'TextArea': template = textAreaTemplate; break; case 'RadioList': template = radioListTemplate; break; } return template; }; element.html(getTemplate(scope.type)); $compile(element.contents())(scope); } }; }]); myApp.controller('DynamicFormController', function () { this.productElement = {}; this.product = { ProductName: 'Online Form', Company: 'TEST', Data: [] }; this.productItems = [{ ProductLabel: "Status", ProductType: "SelectListItem", ProductData: [{ "Text": "Item1", "Value": "1", Selected: true }, { "Text": "Item2", "Value": "2" }] }, { ProductLabel: "Publication", ProductType: "SelectListItem", ProductData: [{ Text: 'Item1', Value: '1' }, { Text: 'Item2', Value: '2', Selected: true }] }, { ProductLabel: "Caption", ProductType: "TextArea", ProductData: "this is some data for the textarea" }, { ProductLabel: "Display Advertising", ProductType: "RadioList", ProductData: { Name: "classifiedAdvertising", Items: [{ Text: 'Full Page', Selected: true }, { Text: '1/2 Page' }] } }, { ProductLabel: "Status2", ProductType: "SelectListItem", ProductData: [{ "Text": "Item1", "Value": "1" }, { "Text": "Item2", "Value": "2" }, { "Text": "Item3", "Value": "3", Selected: true }] }, ]; this.save = function () { this.product.Data = this.productItems; console.log('in save', this.product); }; });<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.4.0/lodash.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> <div class="col-sm-12" ng-app="myApp"> <br /> <form class="form-horizontal" ng-controller="DynamicFormController as ctrl"> <div class="form-group" ng-repeat="item in ctrl.productItems"> <label class="col-sm-2 control-label">{{ item.ProductLabel }}</label> <div class="col-sm-10"> <io-product-element data-model="ctrl.productElement[item.ProductLabel]" data-type="item.ProductType" data-data="item.ProductData"></io-product-element> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="button" class="btn btn-info" data-ng-click="ctrl.save()" value="Submit" /> product: {{ ctrl.product | json }} </div> </div> </form> </div>最满意答案
尝试在第一个开关案例中添加break语句
//[...] switch (type) { case 'SelectListItem': template = dropdownTemplate; scope.model = _.find(scope.data, { Selected: true }); break; case 'TextArea': template = textAreaTemplate; break; case 'RadioList': template = radioListTemplate; break; } //[...]Try To add a break statement in the first switch case
//[...] switch (type) { case 'SelectListItem': template = dropdownTemplate; scope.model = _.find(scope.data, { Selected: true }); break; case 'TextArea': template = textAreaTemplate; break; case 'RadioList': template = radioListTemplate; break; } //[...]
更多推荐
发布评论