Javascript 如何从指令中的templateUrl运行$scope函数?
这里有一个plnkr向您展示所有代码:(我试图只展示必要的内容,但我想展示任务排序的进展情况,因为这最终是我想要实现的) 如果$scope函数是从index.html触发的,而不是从repeat.html(templateUrl)触发的,那么我可以在控制器中运行$scope函数@加藤已经明确表示,我将需要使用转置,但在尝试了一段时间后,我无法找到它。当我设置transclude:true并将ng transclude添加到in repeat.html中时,似乎没有显示任何内容Javascript 如何从指令中的templateUrl运行$scope函数?,javascript,angularjs,firebase,angularfire,Javascript,Angularjs,Firebase,Angularfire,这里有一个plnkr向您展示所有代码:(我试图只展示必要的内容,但我想展示任务排序的进展情况,因为这最终是我想要实现的) 如果$scope函数是从index.html触发的,而不是从repeat.html(templateUrl)触发的,那么我可以在控制器中运行$scope函数@加藤已经明确表示,我将需要使用转置,但在尝试了一段时间后,我无法找到它。当我设置transclude:true并将ng transclude添加到in repeat.html中时,似乎没有显示任何内容 //index.h
//index.html
<body ng-controller="MainCtrl">
<section>
<form ng-submit="addTask(task); task.title=null">
<input placeholder="Add Task" ng-model="task.title" />
</form>
<repeat-by-week collection="list"></repeat-by-week>
</section>
</body>
//repeat.html (the templateUrl file)
<ul class="tasks-list">
<li ng-repeat="week in weeks">
<ul>
<li ng-repeat="day in week.days">
<h4>{{day.time | date:"MMMM dd'th'" }}</h4>
<ul>
<li ng-repeat="task in day.items">
<input type="checkbox" ng-model="task.complete" ng-change="isCompleteTask(task)">
<input ng-model="task.title" ng-change="updateTask(task)">
<button ng-click="deleteTask(task)">x</button>
</li>
</ul>
</li>
</ul>
</li>
</ul>
//the controller (I can access $scope.addTask but not update, delete, or complete)
angular.module('app').controller('MainCtrl', function($scope, $firebase){
var ref = new Firebase('https://plnkr.firebaseio.com/tasks');
$scope.list = $firebase(ref).$asArray();
$scope.addTask = function(newTask) {
$scope.list.$add({
title: newTask.title,
$priority: Firebase.ServerValue.TIMESTAMP,
complete: false,
completeTime: '',
createTime: Firebase.ServerValue.TIMESTAMP
});
};
$scope.deleteTask = function(task){
alert('delete task was clicked');
$scope.list.$remove(task);
};
$scope.updateTask = function(task){
$scope.list.$save(task);
};
$scope.isCompleteTask = function(task){
if(task.completeTime){
task.completeTime = '';
} else{
task.completeTime = Firebase.ServerValue.TIMESTAMP;
}
$scope.list.$save(task);
};
});
//the directive
angular.module('app').directive('repeatByWeek', function($parse, $window) {
return {
restrict: 'E',
replace: true,
templateUrl: 'repeat.html',
scope: {
'master': '=collection'
},
link: function(scope, el, attrs) {
// get the global moment lib
var moment = $window.moment;
scope.weeks = [];
updateList();
// whenever the source collection changes, update our nested list
scope.master.$watch(updateList);
function updateList() {
scope.weeks = sortItems(parseItems(scope.master));
}
function sortItems(sets) {
var items = [];
// get a list of weeks and sort them
var weeks = sortDescending(Object.keys(sets));
for(var i=0, wlen=weeks.length; i < wlen; i++) {
var w = weeks[i];
// get a list of days and sort them
var days = sortDescending(Object.keys(sets[w]));
var weekEntry = {
time: w,
days: []
};
items.push(weekEntry);
// now iterate the days and add entries
for(var j=0, dlen=days.length; j < dlen; j++) {
var d = days[j];
weekEntry.days.push({
time: d,
// here is the list of tasks from parseItems
items: sets[w][d]
});
}
}
console.log('sortItems', items);
return items;
}
// take the array and nest it in an object by week and then day
function parseItems(master) {
var sets = {};
angular.forEach(master, function(item) {
var week = moment(item.$priority).startOf('week').valueOf();
var day = moment(item.$priority).startOf('day').valueOf();
if( !sets.hasOwnProperty(week) ) {
sets[week] = {};
}
if( !sets[week].hasOwnProperty(day) ) {
sets[week][day] = [];
}
sets[week][day].push(item);
});
console.log('parseItems', sets);
return sets;
}
function sortDescending(list) {
return list.sort().reverse();
}
}
};
});
//index.html
//repeat.html(模板URL文件)
-
-
{{day.time{date:'MMMM dd'th'}
-
x
//控制器(我可以访问$scope.addTask,但不能更新、删除或完成)
角度.module('app').controller('MainCtrl',function($scope,$firebase){
var ref=新的Firebase('https://plnkr.firebaseio.com/tasks');
$scope.list=$firebase(ref)。$asArray();
$scope.addTask=函数(newTask){
$scope.list.$add({
标题:newTask.title,
$priority:Firebase.ServerValue.TIMESTAMP,
完成:错误,
completeTime:“”,
createTime:Firebase.ServerValue.TIMESTAMP
});
};
$scope.deleteTask=函数(任务){
警报(“已单击删除任务”);
$scope.list.$remove(任务);
};
$scope.updateTask=函数(任务){
$scope.list.$save(任务);
};
$scope.isCompleteTask=函数(任务){
if(任务完成时间){
task.completeTime='';
}否则{
task.completeTime=Firebase.ServerValue.TIMESTAMP;
}
$scope.list.$save(任务);
};
});
//指令
angular.module('app')。指令('repeatByWeek',函数($parse,$window){
返回{
限制:'E',
替换:正确,
templateUrl:'repeat.html',
范围:{
“主控”:“=集合”
},
链接:功能(范围、el、属性){
//获取全局矩库
var矩=$window.moment;
scope.weeks=[];
updateList();
//每当源集合更改时,更新嵌套列表
scope.master.$watch(更新列表);
函数updateList(){
scope.weeks=sortItems(parseItems(scope.master));
}
功能菌落数(组){
var项目=[];
//获取一份周的列表并对其进行排序
var weeks=sortdescenting(Object.keys(set));
对于(变量i=0,wlen=weeks.length;i
如何从repeat.html文件中的控制器访问$scope.update、delete和complete函数(或者将repeat.html文件移动到index.html中,如果这允许我访问这些函数) 您已经有了一个独立的作用域,因此您可以只绑定控制器中需要的函数,您可以这样做(只显示不同部分的相关代码): Inside Index.html:
<repeat-by-week collection="list" update-task='updateTask(task)' delete-task='deleteTask(task)' is-complete-task='isCompleteTask(task)' ></repeat-by-week>
Inside repeat.html:
<li ng-repeat="task in day.items">
<input type="checkbox" ng-model="task.complete" ng-change="isCompleteTask({task:task})">
<input ng-model="task.title" ng-change="updateTask({task:task})">
<button ng-click="deleteTask({task:task})">x</button>
</li>
x
您是否尝试过
$scope.$parent.update()
以查看这是否是一个孤立的作用域问题。这似乎没有任何效果$范围。$parent.updateTask…如果您使用的是Chrome。您可以通过选择DOM元素来检查作用域,然后在控制台中键入$($0).scope()
。是的,您是对的,它是隔离作用域。这里存在分离关注点的问题。您的指令与控制器紧密耦合。您应该真正创建一个执行操作的服务,而不是将所有内容都放在控制器中。您应该在指令上为其使用者可以使用的操作绑定一个函数,或者您的指令应该是自行执行删除的容器。您正在尝试解决这个问题。$($0).scope()返回未定义的@MathewFoscarin如果我做了一个转移,这有必要吗?在这种情况下,转移是否更难实现?我似乎找不到一门课程(付费或免费)来涵盖我的具体情况,也没有足够的解释让我能够做到。@PSL哇!我没有阅读问题的评论,我不敢相信我得到了正确的答案
<li ng-repeat="task in day.items">
<input type="checkbox" ng-model="task.complete" ng-change="isCompleteTask({task:task})">
<input ng-model="task.title" ng-change="updateTask({task:task})">
<button ng-click="deleteTask({task:task})">x</button>
</li>