Javascript 如何在'中正确绑定对象;绑定';在angular.js 1中使用$compile?

Javascript 如何在'中正确绑定对象;绑定';在angular.js 1中使用$compile?,javascript,angularjs,angularjs-directive,angularjs-scope,angularjs-components,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,Angularjs Components,我想动态编译组件,以便将其插入特定的DOM元素(DOM也是由第三方库动态创建的)。 因此,我使用$compile,$scope 但是下面的$onChanges生命周期钩子在ListItemController中没有执行 // ListItemController $onChanges life cycle hook function $onChanges(changes) { if (!changes.item.isFirstChange()) { $log.debug(chan

我想动态编译组件,以便将其插入特定的DOM元素(DOM也是由第三方库动态创建的)。 因此,我使用
$compile
$scope

但是下面的
$onChanges
生命周期钩子在
ListItemController
中没有执行

// ListItemController $onChanges life cycle hook

function $onChanges(changes) {
  if (!changes.item.isFirstChange()) {
    $log.debug(changes);  // Not executed
  }
}
我猜
angular.merge
ListItemController
控制器实例初始化之前传递
item
是一个主要原因

var itemScope = $scope.$new(true, $scope);
itemScope = angular.merge(itemScope, {
  $ctrl: {
    item: item
  }
});

我对您的代码进行了一些修改,以演示使用单向绑定的情况

angular.module('app', [
    'list.component',
    'list-item.component'
]);

/**
 * list.component
 */
angular
    .module('list.component', [])
    .component('list', {
        controller: ListController,
        template: '<div id="list"></div>'
    });

ListController.$inject = ['$compile', '$document', '$log', '$scope', '$timeout'];
function ListController($compile, $document, $log, $scope, $timeout) {
    var ctrl = this;

    ctrl.$onInit = $onInit;
    ctrl.$postLink = $postLink;

    function $onInit() {
        ctrl.items = [
            {
                id: 0,
                value: 'a'
            },
            {
                id: 1,
                value: 'b'
            },
            {
                id: 2,
                value: 'c'
            }
        ];
    }

    function $postLink() {
        var index = 0;
        // Not entirely sure what you need to do this. This can easily be done in the template.
        /** ie:
         * template: '<div id="list" ng-repeat="item in $ctrl.items"><list-item item="item"></list-item></div>'
         **/

        var iElements = ctrl.items.map(function (item) {
            var template = '<list-item item="$ctrl.items[' + (index) + ']"></list-item>';
            index++;
            // you don't want to create an isolate scope here for the 1 way binding of the item.
            return $compile(template)($scope.$new(false));
        });

        var listDOM = $document[0].getElementById('list');
        var jqListDOM = angular.element(listDOM);

        iElements.forEach(function (iElement) {
            jqListDOM.append(iElement);
        });

        $timeout(function () {
            // this will trigger $onChanges since this is a reference change
            ctrl.items[0] = { id: 3, value: 'ss' };
            // this however, will not trigger the $onChanges, if you need to use deep comparison, consider to use $watch
            ctrl.items[1].value = 's';
            ctrl.items[2].value = 's';
        }, 2000);
    }
}

/**
 * list-item.component
 */
angular
    .module('list-item.component', [])
    .component('listItem', {
        bindings: {
            item: '<'
        },
        controller: ListItemController,
        template: '<div class="listItem">{{ $ctrl.item.value }}</div>'
    });

ListItemController.$inject = ['$log'];
function ListItemController($log) {
    var ctrl = this;

    ctrl.$onChanges = $onChanges;

    function $onChanges(changes) {
        if (!changes.item.isFirstChange()) {
            $log.debug(changes);    // Not executed      
        }
    }
}
angular.module('app'[
'列表.组件',
'列表项.组件'
]);
/**
*列表.组件
*/
有棱角的
.module('list.component',[])
.组件('列表'{
控制器:ListController,
模板:“”
});
ListController.$inject=[“$compile”、“$document”、“$log”、“$scope”、“$timeout”];
函数ListController($compile、$document、$log、$scope、$timeout){
var ctrl=this;
ctrl.$onInit=$onInit;
ctrl.$postLink=$postLink;
函数$onInit(){
ctrl.items=[
{
id:0,
值:“a”
},
{
id:1,
值:“b”
},
{
id:2,
值:“c”
}
];
}
函数$postLink(){
var指数=0;
//不完全确定您需要做什么。这可以在模板中轻松完成。
/**即:
*模板:“”
**/
var iElements=ctrl.items.map(函数(项){
var模板=“”;
索引++;
//您不希望在此处为项的单向绑定创建隔离作用域。
返回$compile(template)($scope.$new(false));
});
var listDOM=$document[0]。getElementById('list');
var jqListDOM=angular.element(listDOM);
iElements.forEach(函数(iElement){
jqListDOM.append(iElement);
});
$timeout(函数(){
//这将触发$onChanges,因为这是一个引用更改
ctrl.items[0]={id:3,值:'ss'};
//但是,这不会触发$Onchange,如果需要使用深度比较,考虑使用$WAT。
ctrl.items[1]。值='s';
ctrl.items[2]。值='s';
}, 2000);
}
}
/**
*list-item.component
*/
有棱角的
.module('list-item.component',[])
.component('listItem'{
绑定:{

item:“我对您的代码进行了一些修改,以演示使用单向绑定的情况

angular.module('app', [
    'list.component',
    'list-item.component'
]);

/**
 * list.component
 */
angular
    .module('list.component', [])
    .component('list', {
        controller: ListController,
        template: '<div id="list"></div>'
    });

ListController.$inject = ['$compile', '$document', '$log', '$scope', '$timeout'];
function ListController($compile, $document, $log, $scope, $timeout) {
    var ctrl = this;

    ctrl.$onInit = $onInit;
    ctrl.$postLink = $postLink;

    function $onInit() {
        ctrl.items = [
            {
                id: 0,
                value: 'a'
            },
            {
                id: 1,
                value: 'b'
            },
            {
                id: 2,
                value: 'c'
            }
        ];
    }

    function $postLink() {
        var index = 0;
        // Not entirely sure what you need to do this. This can easily be done in the template.
        /** ie:
         * template: '<div id="list" ng-repeat="item in $ctrl.items"><list-item item="item"></list-item></div>'
         **/

        var iElements = ctrl.items.map(function (item) {
            var template = '<list-item item="$ctrl.items[' + (index) + ']"></list-item>';
            index++;
            // you don't want to create an isolate scope here for the 1 way binding of the item.
            return $compile(template)($scope.$new(false));
        });

        var listDOM = $document[0].getElementById('list');
        var jqListDOM = angular.element(listDOM);

        iElements.forEach(function (iElement) {
            jqListDOM.append(iElement);
        });

        $timeout(function () {
            // this will trigger $onChanges since this is a reference change
            ctrl.items[0] = { id: 3, value: 'ss' };
            // this however, will not trigger the $onChanges, if you need to use deep comparison, consider to use $watch
            ctrl.items[1].value = 's';
            ctrl.items[2].value = 's';
        }, 2000);
    }
}

/**
 * list-item.component
 */
angular
    .module('list-item.component', [])
    .component('listItem', {
        bindings: {
            item: '<'
        },
        controller: ListItemController,
        template: '<div class="listItem">{{ $ctrl.item.value }}</div>'
    });

ListItemController.$inject = ['$log'];
function ListItemController($log) {
    var ctrl = this;

    ctrl.$onChanges = $onChanges;

    function $onChanges(changes) {
        if (!changes.item.isFirstChange()) {
            $log.debug(changes);    // Not executed      
        }
    }
}
angular.module('app'[
'列表.组件',
'列表项.组件'
]);
/**
*列表.组件
*/
有棱角的
.module('list.component',[])
.组件('列表'{
控制器:ListController,
模板:“”
});
ListController.$inject=[“$compile”、“$document”、“$log”、“$scope”、“$timeout”];
函数ListController($compile、$document、$log、$scope、$timeout){
var ctrl=this;
ctrl.$onInit=$onInit;
ctrl.$postLink=$postLink;
函数$onInit(){
ctrl.items=[
{
id:0,
值:“a”
},
{
id:1,
值:“b”
},
{
id:2,
值:“c”
}
];
}
函数$postLink(){
var指数=0;
//不完全确定您需要做什么。这可以在模板中轻松完成。
/**即:
*模板:“”
**/
var iElements=ctrl.items.map(函数(项){
var模板=“”;
索引++;
//您不希望在此处为项的单向绑定创建隔离作用域。
返回$compile(template)($scope.$new(false));
});
var listDOM=$document[0]。getElementById('list');
var jqListDOM=angular.element(listDOM);
iElements.forEach(函数(iElement){
jqListDOM.append(iElement);
});
$timeout(函数(){
//这将触发$onChanges,因为这是一个引用更改
ctrl.items[0]={id:3,值:'ss'};
//但是,这不会触发$Onchange,如果需要使用深度比较,考虑使用$WAT。
ctrl.items[1]。值='s';
ctrl.items[2]。值='s';
}, 2000);
}
}
/**
*list-item.component
*/
有棱角的
.module('list-item.component',[])
.component('listItem'{
绑定:{

item:“$onChanges只侦听您放入绑定中的属性,因为
item
不在绑定中,对它的任何更改都不会触发$onChanges函数,您应该使用$watch来代替它。@AnthonyC那么,在
listItem
中编译时如何正确传递
item
中的
objectoller
?$onChanges只侦听您放入绑定中的属性,因为
item
不在绑定中,对它的任何更改都不会触发$onChanges函数,您应该改用$watch。@AnthonyC那么,在
listItem
中编译时如何正确传递
item
组件绑定中的
item
对象呢t控制器