>  기사  >  웹 프론트엔드  >  Angular.js로 개발할 때 주의할 점

Angular.js로 개발할 때 주의할 점

高洛峰
高洛峰원래의
2016-12-09 16:07:161014검색

머리말

저는 최근에 Angularjs를 사용해 봤습니다. Knockout에 비해 Angularjs의 MVVM 프레임워크는 더 강력하고 복잡하지만 다양한 튜토리얼이 인터넷에 있습니다. 프로젝트에서 실제로 사용되는 것들이 때때로 다양한 함정에 직면하게 될 것입니다.

1.ng-repeat

ng-repeat는 요소가 반복적으로 출력되어야 함을 식별하는 데 사용되며, 반복 출력의 내용은 고유해야 합니다

<div ng-app="app" ng-controller="control">
  <h3 ng-repeat="content in repeatContent">ng-repeat: {{ content }}</h3>
</div>

let app = angular.module("app", []);
app.controller("control", ($scope) => {
  // 输出李滨泓
  $scope.repeatContent = ["李", "滨", "泓"];
  // 下面存在两个“泓”,会报错
  // $scope.repeatContent = ["李", "滨", "泓", "泓"];
})

2. 공급자, 서비스, 공장

공장

factory는 서비스와 매우 유사합니다. 차이점은 서비스가 Angular의 싱글톤 개체라는 것입니다. 즉, 서비스를 사용해야 할 때 new 키워드를 사용하여 하나의(단 하나의) 서비스를 생성합니다. Factory는 필요할 때 일반 함수를 호출하는 방법일 뿐입니다. 예를 들어 함수 함수의 컬렉션 개체를 반환하여 사용할 수 있습니다.

정의:

let app = angular.module("app", []);
 
// 这里可以注入 $http 等 Provider
app.factory("Today", () => {
  let date = new Date();
  return {
    year: date.getFullYear(),
    month: date.getMonth() + 1,
    day: date.getDate()
  };
});

주사 사용:

app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});

service

service는 사용될 때 싱글톤 객체이며 생성자이기도 합니다. 그 특성상 new 키워드를 사용하여 생성되고 다음에서 사용할 수 있기 때문입니다. 컨트롤러 컨트롤러 간의 통신 및 데이터 상호 작용, 컨트롤러의 범위 체인이 쓸모 없게 되면 파괴되기 때문입니다(예: 다른 컨트롤러를 사용하는 동안 라우팅을 사용하여 다른 컨트롤러를 사용하는 동안 다른 페이지로 이동)

정의:

let app = angular.module("app", []);
 
// 这里可以注入 $http 等 Provider
// 注意这里不可以使用 arrow function
// arrow function 不能作为 constructor
app.service("Today", function() {
  let date = new Date();
  this.year = date.getFullYear();
  this.month = date.getMonth() + 1;
  this.day = date.getDate();
});

삽입 사용:

app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});

공급자

공급자 예 서비스의 기본 생성 방법에 관해서는 공급자가 서비스의 구성 가능한 버전이라는 것을 이해할 수 있습니다. 공급자를 공식적으로 주입하기 전에 공급자의 일부 매개 변수를 구성할 수 있습니다.

정의:

let app = angular.module("app", []);
 
// 这里可以注入 $http 等 Provider
// 注意这里不可以使用 arrow function
// arrow function 不能作为 constructor
app.provider("Today", function() {
  this.date = new Date();
  let self = this;
 
  this.setDate = (year, month, day) => {
    this.date = new Date(year, month - 1, day);
  }
 
  this.$get = () => {
    return {
      year: this.date.getFullYear(),
      month: this.date.getMonth() + 1,
      day: this.date.getDate()
    };
  };
});

주사 사용:

// 这里重新配置了今天的日期是 2015年2月15日
// 注意这里注入的是 TodayProvider,使用驼峰命名来注入正确的需要配置的 provider
app.config((TodayProvider) => {
  TodayProvider.setDate(2015, 2, 15);
});
 
app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});

3. 핸들바와 각도 기호 해상도 간의 충돌

시나리오:

node.js를 서버로 사용하고 핸들바를 템플릿 엔진으로 사용할 때 노드 .js는 템플릿이 {{} }를 변수 구문 분석 기호로 사용하기 때문에 특정 URL에 응답하고 렌더링합니다. 마찬가지로 각도도 {{} }를 가변 해상도 기호로 사용하므로 node.js가 페이지를 렌더링할 때 {{} }의 변수가 존재하지 않으면 해당 영역이 지워지는데 원래 의도는 이렇습니다. 핸들바 대신 Angle의 파싱을 위해 동시에 핸들바도 계속 사용하고 싶기 때문에 이번에는 Angle의 기본 { {} } 파싱 기호를 다시 정의해야 합니다. 즉, 다음 예와 같이 종속성 주입 $interpolateProvider를 사용하여 정의합니다.

app.config($interpolateProvider => {
  $interpolateProvider.startSymbol(&#39;{[{&#39;);
  $interpolateProvider.endSymbol(&#39;}]}&#39;);
});

4. ng-annotate-loader

ng -annotate-loader는 webpack +angular 개발 시나리오에 적용됩니다.Angular 압축 후 의존성 주입이 실패하고 오류가 발생하는 문제를 해결하기 위한 솔루션입니다.

설치

$ npm install ng-annotate-loader --save-dev

구성

// webpack.config.js
{
  test: /\.js?$/,
  exclude: /(node_modules|bower_components)/,
  loader: &#39;ng-annotate!babel?presets=es2015&#39;
},

5. 🎜>

Angular가 아닌 내장 이벤트를 사용할 때 $scope의 데이터 변경으로 인해 $digest의 더티 검사 주기가 발생하지 않습니다. 이로 인해 모델이 동시에 업데이트되지 않습니다. 이 경우 업데이트를 직접 실행해야 합니다.

HTML

<div>{{ foo }}</div>
<button id="addBtn">go</button>

JavaScript

app.controller("control", ($scope) => {
  $scope.foo = 0;
  document.getElementById("addBtn").addEventListener("click", () => {
    $scope.foo++;
  }, false);
})

분명히 이 예제의 의도는 버튼을 클릭하면 foo가 성장하고 View가 업데이트된다는 것입니다. 그러나 실제로는 $scope.foo가 변경됩니다. 그러나 뷰는 새로 고쳐지지 않습니다. foo에는 변경 사항을 감지하는 $watch가 없기 때문에 결국 $digest가 발생하므로 $apply를 직접 트리거하거나 $watch를 생성하여 데이터 변경 사항을 트리거하거나 감지해야 합니다.

JavaScript($apply 사용)

app.controller("control", ($scope) => {
  $scope.foo = 0;
  document.getElementById("addBtn").addEventListener("click", () => {
     
    $scope.$apply(function() {
      $scope.foo++;
    });
 
  }, false);
})

JavaScript($watch 및 $digest 사용)

app.controller("control", ($scope) => {
  $scope.foo = 0;
  $scope.flag = 0;
 
  $scope.$watch("flag", (newValue, oldValue) => {
 
    // 当 $digest 循环检测 flag 时,如果新旧值不一致将调用该函数
    $scope.foo = $scope.flag;
  });
 
  document.getElementById("addBtn").addEventListener("click", () => {
     
    $scope.flag++;
    // 主动触发 $digest 循环
    $scope.$digest();
  }, false);
})

6. $watch(watchExpression, Listener, [objectEquality] )

watchExpression 값이 변경될 때마다 호출되는 리스너 콜백 함수를 등록합니다

watchExpression은 $digest가 실행될 때마다 호출되어 감지할 값을 반환합니다(다중일 때 동일한 값이 두 번 입력될 때 watchExpression은 자체 값을 변경해서는 안 됩니다. 그렇지 않으면 다중 $digest 루프가 발생할 수 있습니다. watchExpression은 멱등성)


리스너는 현재 watchExpression 반환 값에 있고 watchExpression 시간의 반환 값이 일치하지 않을 때 호출됩니다(==를 사용하는 대신 불일치를 엄격하게 판단하려면 !==를 사용하세요. for objectEquality == true)


objectEquality는 부울 값입니다. true인 경우, angle.equals는 일관성을 결정하는 데 사용되고, angle.copy는 해당 개체의 복사본을 저장하는 데 사용됩니다. 다음 비교는 복잡한 개체 감지에 성능 및 메모리 문제가 있음을 의미합니다.


7. $apply([exp])

$apply는 $scope의 함수입니다. $digest 루프를 트리거하려면

$apply pseudo code

function $apply(expr) {
  try {
    return $eval(expr);
  } catch (e) {
    $exceptionHandler(e);
  } finally {
    $root.$digest();
  }
}

$eval(expr)을 사용하여 expr 표현식을 실행하세요.


실행 중 예외가 발생하면 $ExceptionHandler(e)를 실행합니다.


결국 결과에 관계없이 $digest 루프가 실행됩니다


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.