将AngularJS范围变量从指令传递给控制器的最简单方法是什么?我见过的所有例子看起来都很复杂,是不是我可以从指令访问控制器,并设置其中一个范围变量?
如果我有一个指令响应范围上特定属性的状态,并且我想在我的测试中更改该属性并验证它是否正确响应,这是进行更改的最佳方法?
我见过这两种模式:
scope.$apply(function() {
scope.myAttribute = true;
});
Run Code Online (Sandbox Code Playgroud)
和
scope.myAttribute = true;
scope.$digest();
Run Code Online (Sandbox Code Playgroud)
它们之间有什么区别,哪个更好,为什么?
我有一个带隔离范围的指令(这样我可以在其他地方重用该指令),当我使用这个指令时ng-repeat,它无法工作.
我已阅读有关此主题的所有文档和Stack Overflow答案,并了解问题.我相信我已经避免了所有常见的陷阱.
所以我理解我的代码因ng-repeat指令创建的范围而失败.我自己的指令创建了一个isolate-scope,并对父作用域中的对象进行双向数据绑定.我的指令将为这个绑定变量赋一个新的对象值,当我的指令没有使用时ng-repeat(父变量被正确更新),这种方法非常有效.但是,使用ng-repeat,赋值在ng-repeat作用域中创建一个新变量,而父变量看不到更改.所有这些都是基于我所读到的预期.
我还读到,当给定元素上有多个指令时,只创建一个范围.并且priority可以在每个指令中设置a 来定义指令的应用顺序; 指令按优先级排序,然后调用它们的编译函数(在http://docs.angularjs.org/guide/directive上搜索单词优先级).
所以我希望我可以使用优先级来确保我的指令首先运行并最终创建一个隔离范围,并且在ng-repeat运行时,它重新使用隔离范围而不是创建原型继承父范围的范围.该ng-repeat文档声明该指令以优先级运行1000.目前尚不清楚1是优先级更高还是优先级更低.当我1在我的指令中使用优先级时,它没有任何区别,所以我尝试了2000.但这会让事情变得更糟:我的双向绑定变成了undefined我的指令并没有显示任何东西.
我创造了一个小提示来展示我的问题.我已经priority在我的指令中注释掉了这个设置.我有一个名称对象列表和一个名为对象的指令name-row,它显示了名称对象中的名字和姓氏字段.单击显示的名称时,我希望它selected在主范围中设置变量.名称数组,selected变量name-row使用双向数据绑定传递给指令.
我知道如何通过调用主范围中的函数来使其工作.我也知道如果selected在另一个对象内部,并且我绑定到外部对象,事情就会起作用.但我现在对这些解决方案不感兴趣.
相反,我的问题是:
ng-repeat从创建prototypically从父范围继承的范围,而是把它用我的指令的分离,范围有多大?2000我的指令中的优先级不起作用?angularjs angularjs-directive angularjs-scope angularjs-ng-repeat
我有一个元素,我想将HTML绑定到它.
<div ng-bind-html="details" upper></div>
这样可行.现在,除此之外,我还有一个绑定到绑定html的指令:
$scope.details = 'Success! <a href="#/details/12" upper>details</a>'
但是upperdiv和锚的指令没有评估.我如何使其工作?
我似乎无法在不使用隔离范围的情况下从指令中调用父作用域上的函数.我知道如果我使用隔离范围,我可以在隔离中使用"&"来访问父范围上的函数,但是在没有必要时使用隔离范围会产生后果.请考虑以下HTML:
<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
Run Code Online (Sandbox Code Playgroud)
在这个简单的例子中,我想显示一个JavaScript确认对话框,如果他们在确认对话框中单击"确定",则只调用doIt().使用隔离范围很简单.该指令看起来像这样:
.directive('confirm', function () {
return {
restrict: 'A',
scope: {
confirm: '@',
confirmAction: '&'
},
link: function (scope, element, attrs) {
element.bind('click', function (e) {
if (confirm(scope.confirm)) {
scope.confirmAction();
}
});
}
};
})
Run Code Online (Sandbox Code Playgroud)
但问题是,因为我使用的是隔离范围,上面示例中的ng-hide不再针对父范围执行,而是在隔离范围内执行(因为在任何指令上使用隔离范围会导致该元素上的所有指令使用孤立的范围).这是上面例子的jsFiddle,其中ng-hide不起作用.(请注意,在此小提琴中,当您在输入框中键入"yes"时,该按钮应隐藏.)
替代方案是不使用隔离范围,这实际上是我真正想要的范围,因为不需要隔离此指令的范围.我唯一的问题是,如果我没有在隔离范围内传递它,如何在父范围上调用方法?
这是一个jsfiddle我不使用隔离范围,ng-hide工作正常,但是,当然,对confirmAction()的调用不起作用,我不知道如何使它工作.
请注意,我真正寻找的答案是如何在外部作用域上调用函数而不使用隔离的作用域.我不想以另一种方式使这个确认对话框工作,因为这个问题的关键是要弄清楚如何调用外部作用域,并且仍然能够使其他指令对父作用域起作用.
或者,如果其他指令仍然适用于父作用域,我有兴趣听到使用隔离作用域的解决方案,但我认为这不可行.
我的AngularJS模板包含一些自定义HTML语法,如:
<su-label tooltip="{{field.su_documentation}}">{{field.su_name}}</su-label>
Run Code Online (Sandbox Code Playgroud)
我创建了一个指令来处理它:
.directive('suLabel', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
title: '@tooltip'
},
template: '<label><a href="#" rel="tooltip" title="{{title}}" data-placement="right" ng-transclude></a></label>',
link: function(scope, element, attrs) {
if (attrs.tooltip) {
element.addClass('tooltip-title');
}
},
}
})
Run Code Online (Sandbox Code Playgroud)
一切正常,除了attrs.tooltip表达式,它总是返回undefined,即使该tooltip属性在进行操作时可以从谷歌Chrome的JavaScript控制台中看到console.log(attrs).
有什么建议吗?
更新:Artem提供了一个解决方案.它包括这样做:
link: function(scope, element, attrs) {
attrs.$observe('tooltip', function(value) {
if (value) {
element.addClass('tooltip-title');
}
});
}
Run Code Online (Sandbox Code Playgroud)
AngularJS + stackoverflow =幸福
我不太明白何时使用指令以及何时使用nginclude更合适.举个例子:我有一个部分,password-and-confirm-input-fields.html就是用于输入和确认密码的html.我在注册页面和更改密码页面下使用它.这两个页面各有一个控制器,部分html没有专用控制器.
我应该使用指令还是ngInclude为此?
为什么replace=true还是replace=false没有在下面的代码产生任何影响?
当replace = false时,为什么不显示"某些现有内容"?
或者更谦虚地说,你能否解释一下replace=true/false指令中的功能是什么以及如何使用它?
例
JS /角:
<script>
angular.module('scopes', [])
.controller('Ctrl', function($scope) {
$scope.title = "hello";
})
.directive('myDir', function() {
return {
restrict: 'E',
replace: true,
template: '<div>{{title}}</div>'
};
});
</script>
Run Code Online (Sandbox Code Playgroud)
HTML:
<div ng-controller="Ctrl">
<my-dir><h3>some existing content</h3></my-dir>
</div>
Run Code Online (Sandbox Code Playgroud)
在Plunker中看到它:
这是主模板的控制器:
app.controller('OverviewCtrl', ['$scope', '$location', '$routeParams', 'websiteService', 'helperService', function($scope, $location, $routeParams, websiteService, helperService) {
...
$scope.editWebsite = function(id) {
$location.path('/websites/edit/' + id);
};
}]);
Run Code Online (Sandbox Code Playgroud)
这是指令:
app.directive('wdaWebsitesOverview', function() {
return {
restrict: 'E',
scope: {
heading: '=',
websites: '=',
editWebsite: '&'
},
templateUrl: 'views/websites-overview.html'
}
});
Run Code Online (Sandbox Code Playgroud)
这是指令在主模板中的应用方式:
<wda-websites-overview heading="'All websites'" websites="websites" edit-website="editWebsite(id)"></wda-websites-overview>
Run Code Online (Sandbox Code Playgroud)
这是从指令模板(website-overview.html)调用的方法:
<td data-ng-click="editWebsite(website.id)">EDIT</td>
Run Code Online (Sandbox Code Playgroud)
问题:单击EDIT时,控制台中会出现此错误:
TypeError:无法使用"in"运算符在1中搜索"editWebsite"
有谁知道这里发生了什么?
我有一个表单,如果复选框为false,则使用ng-required指令对文本输入强制执行验证.如果复选框为true,则隐藏该字段,并将ng-required设置为false.
问题是我还在输入上指定了验证的正则表达式,并使用了ng-pattern angular指令.我遇到的问题是,如果用户填写了无效的电话号码,请选中该框以停用该输入(因此无需进一步验证),表单将不允许提交,因为它基于ng-pattern无效.
我尝试通过添加ng-change函数来将输入模型设置为null来解决此问题,但是ng-pattern和字段仍然在复选框的初始设置为false时设置为无效.但是,如果我取消选中该框,将所有内容设置回初始表单加载,然后再次选中该框,表单有效并且能够提交.我不确定我错过了什么.这是我到目前为止的ng-change代码:
var phoneNumberRegex = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
$scope.phoneNumberPattern = phoneNumberRegex;
$scope.removeValidation = function() {
if ($scope.cell._newUser === false) {
$scope.request._number = '';
$scope.phoneNumberPattern = /[0-9a-zA-Z]?/;
} else {
$scope.phoneNumberPattern = phoneNumberRegex;
}
};
Run Code Online (Sandbox Code Playgroud)