一个Angular指令使用另一个

时间:2016-03-04 09:31:18

标签: angularjs

我有两个指令,一个显示一个名称周围的小方框(它需要ID,后端询问实际名称是什么),第二个是绘制一张漂亮的卡片(OK卡)。如果我将这张卡用作html它会起作用,但作为一个指令,第一个“盒子”指令不起作用。好的,我可以将功能和API请求移到第二个指令中,但这似乎不对,我还需要使用promise I recon。

另一种选择是编译,但我不确定要编译什么以及如何编译。我希望(或者我想要)将其添加到DOM中,因此他们调用skillBox指令并在何时获取响应。

第一个指令(skillBox)

knowledge.directive('skillBox', function(cvFactory){
    return {
        restrict: 'E',
        scope: { skill: '='},
        link: function (scope, element, attrs) {
            console.log("Got called")
            scope.$watch('skill', function(skill) {
                cvFactory.getNameById(skill.skill, function(idName){
                    console.log("Got name " + idName)
                    var color;
                    if ( skill.score > 79) {
                        color = "green";
                    } else if ( skill.score > 49 ) {
                        color = "yellow";
                    } else {
                        color = "grey"
                    }
                    element.addClass('skillbox')
                    element.css("background-color",color);
                    element.html(idName);
                    //return idName
                });


                //'<span class="skillbox" style="background-color: ' + color + '">' + idName + '</span>'
            })
            scope.$watch('skill.score', function(newScore){
                console.log("newscore"+ newScore);
                var color;
                if ( newScore > 79) {
                    color = "green";
                } else if ( newScore > 49 ) {
                    color = "yellow";
                } else {
                    color = "grey"
                }
                element.css("background-color",color);
                //var cuHtml = element.html();

                //var skillbox = element[0].getElementsByClassName('skillbox');

                //element.html('<span class="skillbox" style="background-color: ' + color + '">' + idName + '</span>');
            })
            //scope.name = myData.name;
        }
    }
})

第二个(我想称之为第一个)

knowledge.directive('showCvCard', function(cvFactory){
    return {
        restrict: 'E',
        scope: { minimized: '=',
                cv: '='},
        link: function ($scope, element, attrs) {
            var minimizedInt = true;
            console.log("Got called")
            $scope.$watch('minimized', function(newValue){
                console.log("New minimized value " + newValue)
                minimizedInt = newValue
            })
            $scope.$watch('cv', function(newValue) {
                //console.log("minimized is now " + newValue.minimized)
                var carddata;
                carddata='<md-card class="md-padding"">'
                carddata=carddata + '<md-card-title layout="row">'
                carddata=carddata + '<md-card-title-media layout="column" layout-align="top end">'
                carddata=carddata + '<div class="md-media-md card-media"><img src="'+newValue.profileImg.dataURL+'" type="" class="profile-pic" alt="Profile view"></div>'
                carddata=carddata + '</md-card-title-media>'
                carddata=carddata + '<md-card-title-text layout="column">'
                //carddata=carddata + '<span class="md-headline">Name: '+ newValue.firstName+ ' '+ newValue.familyName+'</span>'
                carddata=carddata + '<span class="md-subhead">'+newValue.jobTitle+' - Available - '+ newValue.avail+'</span>'
                carddata=carddata + '<p class="md-body-1">'+ newValue.summary+'</p>'
                carddata=carddata + '<p class="md-body-1">'
                for (var i in newValue._skillSet){
                    var color;
                    var score = newValue._skillSet[i].score
                    if ( score > 79) {
                        color = "green";
                    } else if ( score > 49 ) {
                        color = "yellow";
                    } else {
                        color = "grey"
                    }
                    cvFactory.getNameById(newValue._skillSet[i].skill, function(idName) {
                        console.log('<span class="skillbox" style="background-color:' + color + '">' + idName +'<span>')
                        carddata = carddata + '<span class="skillbox" style="background-color:' + color + '">' +  idName+'<span>'
                    })
                }
                //carddata=carddata + '<p class="md-body-1"> <skill-box skill="skill" ng-repeat="skill in '+ newValue.CV._skillSet+'"></skill-box></p><hr>'
                carddata=carddata + '</md-card-title-text>'
                carddata=carddata + '</md-card-title>'
                carddata=carddata + '<md-card-content style="overflow-y: scroll">'
                //carddata=carddata + '<p class="md-body-1"> <skill-box skill="skill" ng-repeat="skill in iAm.CV._skillSet"></skill-box></p><hr>'
                carddata=carddata + '<p class="md-body-1">{{iAm.CV.CV}}</p>'
                carddata=carddata + '</md-card-content>'
                carddata=carddata + '</md-card>'
                element.html(carddata);
            })

            $scope.minimize = function(){
                if ( $scope.minimized === true ) {
                    $scope.minimized = false;
                } else {
                    $scope.minimized = true;
                }
            }

        }
    }
})

我能以某种方式在编译器中抛出carddata(注意,目前它有点工作,但是由于API,生成了正确的HTML,但只有在其余的carddata已经发送到DOM之后,因此诺)

====简单的解决方案====

使用模板和生活是好的,似乎模板被编译: knowledge.directive('testCv',function(cvFactory){     返回{         限制:'E',         范围:{最小化:'=',         cv:'='},         模板:''+             '' +             '' +             '' +             '' +             '' +             '姓名:{{cv.firstName}}'+             '{{cv.CV.jobTitle}} - 可用 - {{cv.CV.avail}}'+             '{{cv.CV.summary}}

' +             '' +             '' +             '' +             '{{cv.CV.CV}}

' +             '' +             “”     } })

希望它可以帮助某人:)

2 个答案:

答案 0 :(得分:1)

我不确定我是否理解你的问题,但你可以包括&#39;另一个指令作为指令中的依赖。

这是一个小例子:

观点:

<div ng-app="app">
  <country>
    <state> 
      <city>

      </city>
    </state>
  </country>
</div>

初始设置:

var app = angular.module("app",[]);

app.directive("country", function () {
  return {
    restrict: "E",
    controller: function () {
      this.makeAnnouncement = function (message) { 
        console.log("Country says: " + message);
      };
    }
  };
});
app.directive("state", function () {
  return {
    restrict: "E"
  };
});
app.directive("city", function () {
  return {
    restrict: "E",
    require: "^country",
    link: function (scope, element, attrs, countryCtrl) {
      countryCtrl.makeAnnouncement("This city rocks");
    }
  };
});

在这里,我们可以将country指令控制器注入city指令的链接功能。这是通过将require命名方案与父指令名称匹配来实现的。有了这个,父指令的控制器可以在子指令中使用。控制器的这种“继承”在祖先距离上是不变的。

此控制器继承不仅限于单个控制器实例:

});
app.directive("state", function () {
  return {
    restrict: "E",
    controller: function () {
      this.makeLaw = function (law) {
        console.log("Law: " + law);
      };
    }
  };
});
app.directive("city", function () {
  return {
    restrict: "E",
    require: ["^country","^state"],
    link: function (scope, element, attrs, ctrls) {
      ctrls[0].makeAnnouncement("This city rocks");
      ctrls[1].makeLaw("Jump higher");
    }
  };
});

答案 1 :(得分:0)

==========这可能只是作为一个理论上的兴趣======= ==使用模板和控制器==

找到了一种更简单的方法

好的,我发现了一种方法,它不是很漂亮,但对我来说效果很好,因为我希望能够在以后基于ngModel的一些数据来更改它。所以诀窍是让链接首先返回结构,包含所有位,但是留下一个带有id的span,以后可以引用它,在我的例子中我使用&#34; skillSpan&#34; carddata=carddata + '<md-card-content><span id="skillSpan"></span></md-card-content>'。所以cv的范围观察看起来像这样

$scope.$watch('cv', function(newValue) {
            //console.log("minimized is now " + newValue.minimized)
            var carddata;
            carddata='<md-card class="md-padding"">'
            carddata=carddata + '<md-card-title layout="row">'
            carddata=carddata + '<md-card-title-media layout="column" layout-align="top end">'
            carddata=carddata + '<div class="md-media-md card-media"><img src="'+newValue.profileImg.dataURL+'" type="" class="profile-pic" alt="Profile view"></div>'
            carddata=carddata + '</md-card-title-media>'
            carddata=carddata + '<md-card-title-text layout="column">'
            //carddata=carddata + '<span class="md-headline">Name: '+ newValue.firstName+ ' '+ newValue.familyName+'</span>'
            carddata=carddata + '<span class="md-subhead">'+newValue.jobTitle+' - Available - '+ newValue.avail.toLocaleDateString()+'</span>'
            carddata=carddata + '<p class="md-body-1">'+ newValue.summary+'</p>'
            //carddata=carddata + '<p class="md-body-1">'

            //for (var i in newValue._skillSet) {
            //    carddata = carddata +'<skill-box skill="' + newValue._skillSet[i] + '"></skill-box>'
            //}
            carddata=carddata + '</md-card-title-text>'
            carddata=carddata + '</md-card-title>'
            carddata=carddata + '<md-card-content><span id="skillSpan"></span></md-card-content>'
            carddata=carddata + '<md-card-content style="overflow-y: scroll">'
            //carddata=carddata + '<p class="md-body-1"> <skill-box skill="skill" ng-repeat="skill in iAm.CV._skillSet"></skill-box></p><hr>'
            carddata=carddata + '<p class="md-body-1">'+newValue.CV+'</p>'
            carddata=carddata + '</md-card-content>'
            carddata=carddata + '</md-card>'
            element.html(carddata);
            updateSkillBox(newValue._skillSet)
        })

完成后,它会调用一个名为updateSkillBox的函数,该函数会获取id updateSkillBox,然后手动写入id。

    function updateSkillBox(skillSet, filter){
        var skillSpan = angular.element(document.querySelector('#skillSpan'))
        skillSpan.html(''); //This resets it, because we want to
        //console.log(skillSet[i].score)
        for (var i in skillSet) {
            console.log(skillSet[i].score)
            var color;
            var score = skillSet[i].score
            if (score > 79) {
                color = "green";
            } else if (score > 49) {
                color = "yellow";
            } else {
                color = "grey"
            }
            cvFactory.getNameByIdnColor(skillSet[i].skill, color, function (idName, idColor) {
                //console.log('<span class="skillbox" style="background-color:' + color + '">' + idName + '<span>')
                skillSpan.append('<span class="skillbox" style="background-color:' + idColor + '">' + idName + '<span>')
            })
        }
    }

我应该补充一点,目前这个选项可能只在页面上工作一次,因为我正在寻找可以重复的ID,但下一步是,将ID设置为唯一的值