Javascript AngularJS 1.5组件中的DOM操作

Javascript AngularJS 1.5组件中的DOM操作,javascript,css,angularjs,dom,Javascript,Css,Angularjs,Dom,我试图理解AngularJS组件的概念,我开始理解它的原理,但当我尝试实践它时,我发现了一个例子,我不知道如何用组件实现它 我需要实现线性progressbar,它有一个模板,所以逻辑上必须是一个组件,而不是一个指令,但我找不到一种方法在组件中进行DOM操作,在这样一个小组件中有一个指令似乎很奇怪。以下是指令的基本实现: JS angular.module('test', []) .controller('MainCtrl', function($q, $scope) { $scope.

我试图理解AngularJS组件的概念,我开始理解它的原理,但当我尝试实践它时,我发现了一个例子,我不知道如何用组件实现它

我需要实现线性progressbar,它有一个模板,所以逻辑上必须是一个组件,而不是一个指令,但我找不到一种方法在组件中进行DOM操作,在这样一个小组件中有一个指令似乎很奇怪。以下是指令的基本实现:

JS

angular.module('test', [])

.controller('MainCtrl', function($q, $scope) {

  $scope.curVal= 0;

  $scope.maxVal = 100;

})

.directive('progressBar', [function () {

    return {
      restrict: 'E',
      scope: {
        curVal: '@',
        maxVal: '@'
      },
      template: "<div class='progress-bar'>"+
                  "<div class='progress-bar-bar'>testing</div>"+
                "</div>",    

      link: function ($scope, element, attrs) {

        function updateProgress() {
          var progress = 0;

          if ($scope.maxVal) {
            progress = Math.min($scope.curVal, $scope.maxVal) / $scope.maxVal * element.find('.progress-bar').width();
          }

          element.find('.progress-bar-bar').css('width', progress);          
        }

        $scope.$watch('curVal', updateProgress);
        $scope.$watch('maxVal', updateProgress);        
      }
    };  
 }]);
.progress-bar {
  width: 120px;
  height: 18px;
  border-style: solid;
  border-width: 1px;
  background-color: rgba(100,50,100,.60);
  border-color: #aaa;  
}

.progress-bar-bar {
  width: 0px;
  background-color: rgb(100,50,100);
  height: 100%;
  color: #fff;
  font-weight: normal
}
所以,也许我理解一个组件的原理是错误的,但我确实在谷歌上搜索了很多关于它的信息,并认为在我面对这个例子之前我理解了这个原理


所以我的问题是:我可以在组件中以任何方式操纵DOM吗?如果答案是否定的,那么在组件中实现该指令的方法是什么(它是否适用)?我不认为向组件添加指令只是为了更改一些CSS是一个合适的选择,所以我被卡住了。

根据Angular的文档,任何DOM操作都应该使用指令来完成。现在这可能是一项很大的工作,但您始终可以在项目中重用该指令

在高层,指令是DOM元素(如属性、元素名称、注释或CSS类)上的标记,它告诉AngularJS的HTML编译器($compile)将指定的行为附加到该DOM元素(例如通过事件侦听器),甚至转换DOM元素及其子元素

下面是如何使用该指令更改css

app.directive('changeStyle', function () {
return {
    restrict: 'AC',
    link: function (scope, element, attrs) {          
       scope.$watch(attrs.myAttr, function (value) {     
         element.css('background-color', (value ? 'transparent' : attrs.myBgcolor));            
       });                      
    }
}

}))

例如,我制作了一个类似的组件。查看样式替换定义:

模板(myDiv.html):


请参见

以解决您对组件与指令的混淆,如何使用一个而不是另一个是您如何设计应用程序的问题

如果您喜欢坚持使用MVC(MVVM、MVW、MV*)体系结构,那么使用组件就没有什么意义。您只需创建由控制器和指令控制的视图,这些控制器和指令将修改或控制某些DOM元素

MV*应用程序中,在某些情况下,您确实希望将块与页面的其余部分分开,甚至使其可重复使用。您仍然可以为它创建一个组件,但在该体系结构中,坚持使用指令更有意义

从1.5开始,指令非常接近组件的定义。您可以去掉作用域,创建一个控制器……等等,您只需要编写更多的样板代码

如果您希望应用程序遵循组件架构(react、web组件、angular2等),那么应用程序中的所有内容都应该是组件。(登录、导航、页脚等)和组件可以有更小的组件。(文件上载组件可能包含进度条组件)

当需要对DOM元素进行更多的控制时,这就是使用指令的时候。 如果没有适合您的现有角度指示(ngStyle、ngClass、ngShow…等),您可以创建自己的角度指示。(如果希望输入自动获得焦点,可以创建指令)

为了回答进度条的问题,我将这样编写它的组件:

var progressBar = {
  bindings: {
    width: '<'
  },
  template: `<div class="meter">
              <span ng-style="{ 'width' : $ctrl.width }"></span>
            </div>`
}
var progressBar={
绑定:{

width:“如果您使用
ng style
@charlietfl oops,则不需要任何dom操作或链接中的任何js,看起来我真的可以使用ng style并在那里传递值,现在看起来很明显,谢谢,我想您可以将其作为答案发布。您需要将工作作为指令,还是需要一种新的组件方法swer仍然是指令,不回答问题question@JoaozitoPolo我需要组件方法,但据我所知,我需要在组件内部使用指令,ng样式或自定义样式,对吗?谢谢,我想我也可以使用ng样式,正如@charlietfl提到的,解决问题的两种方法如果是简单的css,也可以使用ng类改变抱歉,对我来说@JoaozitoPolo的答案看起来更正确,但我可能错了,如果我错了,请纠正我。谢谢,实际上很难选择最正确的答案,但你的答案使用的依赖性较少,所以我会将其标记为正确。哦,抱歉,只选择一个正确答案并不难。别担心。我也更喜欢@gyc答案,它更容易解释安装并包含组件谢谢你给出了这样一个完整的答案,所以我现在明白了,angular 1.x并不是为组件架构而设计的,它更多的是关于MV*架构,对吗?对于组件架构,像react或angular 2这样的框架更合适,对吗?所以,对于angular 1.x,最好坚持使用directiv只有在需要分离应用程序的某些部分时,才能使用组件,对吗?@IlyaIlin no,从1.5开始,你可以制作100%基于组件的应用程序。这只取决于你(或你的老板)在工作中,我们今年开始的每个应用程序都将基于组件(angular2尚未准备好生产)。我们的内部网100%采用angular 1.5组件。一些团队更老派,我们在其他一些项目中坚持使用MVC。(这也不令人震惊)这是一个观点。组件更现代(时尚),但代码比我们使用MVC时更干净。非常感谢,你真的让我更清楚了
<div class="bgDiv" style="color: {{ $ctrl.color }}">
    myDiv
</div>
component('myDiv', {
    templateUrl: 'myDiv.html',
    bindings: {
        color: '='
    }
}) 
var progressBar = {
  bindings: {
    width: '<'
  },
  template: `<div class="meter">
              <span ng-style="{ 'width' : $ctrl.width }"></span>
            </div>`
}