질문 : jQuery 배경이 있다면“AngularJS에서 생각하기”?
jQuery 에서 클라이언트 측 애플리케이션을 개발하는 데 익숙 하지만 이제 AngularJS 사용을 시작하고 싶습니다. 필요한 패러다임 전환을 설명 할 수 있습니까? 다음은 답을 구하는 데 도움이 될 수있는 몇 가지 질문입니다.
- 클라이언트 측 웹 애플리케이션을 다르게 설계하고 디자인하는 방법은 무엇입니까? 가장 큰 차이점은 무엇입니까?
- 무엇을하고 / 사용하지 말아야합니까? 대신 무엇을 시작해야하나요?
- 서버 측 고려 사항 / 제한 사항이 있습니까?
jQuery
와 AngularJS
간의 자세한 비교를 찾고 있지 않습니다.
답변
1. 페이지를 디자인하지 말고 DOM 조작으로 변경합니다.
jQuery에서 페이지를 디자인 한 다음 동적으로 만듭니다. 이는 jQuery가 증강을 위해 설계되었으며 그 단순한 전제에서 엄청나게 성장했기 때문입니다.
그러나 AngularJS에서는 아키텍처를 염두에두고 처음부터 시작해야합니다. "내가 DOM의이 부분을 가지고 있고 X로 만들고 싶다"는 생각으로 시작하는 대신, 수행하려는 작업부터 시작한 다음 응용 프로그램을 디자인 한 다음 마지막으로 뷰를 디자인해야합니다.
2. jQuery에 AngularJS를 추가하지 마십시오.
마찬가지로 jQuery가 X, Y, Z를 수행한다는 생각으로 시작하지 마세요. 모델과 컨트롤러에 대해 AngularJS를 추가하겠습니다. 이것은 당신이 막 시작했을 때 정말 유혹적입니다. 그래서 저는 새로운 AngularJS 개발자가 적어도 "Angular Way"에 익숙해 질 때까지는 jQuery를 전혀 사용하지 않는 것이 좋습니다.
여기와 메일 링리스트에서 많은 개발자들이 150 또는 200 줄의 코드로 구성된 jQuery 플러그인을 사용하여 이러한 정교한 솔루션을 만든 다음 혼란스럽고 복잡한 $apply
하지만 결국 작동하게됩니다! 문제는 대부분의 경우 jQuery 플러그인이 코드의 일부로 AngularJS로 다시 작성 될 수 있다는 것입니다. 갑자기 모든 것이 이해 가능하고 간단 해집니다.
결론은 이것입니다. 솔루션을 구할 때 먼저 "AngularJS에서 생각하십시오"; 해결책을 생각할 수 없다면 커뮤니티에 문의하십시오. 이 모든 후 더 쉬운 해결책이없는 경우, 다음 jQuery를 도달 주시기 바랍니다. 그러나 jQuery가 버팀목이되게하지 마십시오. 그렇지 않으면 AngularJS를 마스터하지 못할 것입니다.
3. 항상 아키텍처의 관점에서 생각합니다.
먼저 단일 페이지 애플리케이션 이 애플리케이션 이라는 것을 알고 있어야합니다. 웹 페이지가 아닙니다. 따라서 우리는 클라이언트 측 개발자처럼 생각하는 것 외에도 서버 측 개발자처럼 생각해야합니다. 응용 프로그램을 확장 가능하고 테스트 가능한 개별 구성 요소로 나누는 방법을 고려해야합니다.
그럼 어떻게 하나요? "AngularJS에서"어떻게 생각하십니까? 다음은 jQuery와 대조되는 몇 가지 일반적인 원칙입니다.
이 뷰는 "공식 기록"입니다.
jQuery에서는 프로그래밍 방식으로 뷰를 변경합니다. ul
로 정의 된 드롭 다운 메뉴를 가질 수 있습니다.
<ul class="main-menu">
<li class="active">
<a href="#/home">Home</a>
</li>
<li>
<a href="#/menu1">Menu 1</a>
<ul>
<li><a href="#/sm1">Submenu 1</a></li>
<li><a href="#/sm2">Submenu 2</a></li>
<li><a href="#/sm3">Submenu 3</a></li>
</ul>
</li>
<li>
<a href="#/home">Menu 2</a>
</li>
</ul>
jQuery에서 애플리케이션 로직에서 다음과 같이 활성화합니다.
$('.main-menu').dropdownMenu();
보기 만 보면 여기에 기능이 있다는 것이 바로 분명하지 않습니다. 작은 응용 프로그램의 경우 괜찮습니다. 그러나 사소하지 않은 응용 프로그램의 경우 상황이 빠르게 혼란스럽고 유지 관리가 어렵습니다.
그러나 AngularJS에서 뷰는 뷰 기반 기능에 대한 공식 기록입니다. ul
선언은 대신 다음과 같습니다.
<ul class="main-menu" dropdown-menu>
...
</ul>
이 두 가지는 똑같은 일을하지만 AngularJS 버전에서는 템플릿을 보는 모든 사람이 무슨 일이 일어날 지 알고 있습니다. 개발 팀의 새로운 구성원이 합류 할 때마다 그녀는 이것을보고 dropdownMenu
라는 지시문 이 작동하고 있음을 알 수 있습니다. 그녀는 정답을 직관하거나 코드를 살펴볼 필요가 없습니다. 보기는 우리에게 무슨 일이 일어나야하는지 말해주었습니다. 훨씬 더 깨끗합니다.
AngularJS를 처음 접하는 개발자는 종종 다음과 같은 질문을합니다. 특정 종류의 모든 링크를 어떻게 찾고 거기에 지시문을 추가합니까? 개발자는 우리가 답장 할 때 항상 당황합니다. 하지만 그렇게하지 않는 이유는 이것이 half-jQuery, half-AngularJS와 같고 좋지 않기 때문입니다. 여기서 문제는 개발자가 AngularJS의 컨텍스트에서 "jQuery를 수행"하려고한다는 것입니다. 그것은 결코 잘 작동하지 않을 것입니다. 보기 는 공식 기록입니다. 지시문 (아래에 더 자세히 설명) 외부에서는 절대로 DOM을 변경 하지 않습니다. 그리고 지시문이 뷰에 적용되므로 의도가 명확합니다.
기억하세요 : 디자인하지 말고 마크 업하세요. 당신은 설계하고 디자인해야합니다.
데이터 바인딩
이것은 AngularJS의 가장 멋진 기능 중 하나이며 이전 섹션에서 언급 한 종류의 DOM 조작을 수행해야하는 많은 필요성을 줄여줍니다. AngularJS는 뷰를 자동으로 업데이트하므로 필요하지 않습니다! jQuery에서는 이벤트에 응답 한 다음 콘텐츠를 업데이트합니다. 다음과 같은 것 :
$.ajax({
url: '/myEndpoint.json',
success: function ( data, status ) {
$('ul#log').append('<li>Data Received!</li>');
}
});
다음과 같은보기의 경우 :
<ul class="messages" id="log">
</ul>
우려를 혼합하는 것 외에도 앞서 언급 한 의도를 나타내는 것과 동일한 문제가 있습니다. 하지만 더 중요한 것은 DOM 노드를 수동으로 참조하고 업데이트해야한다는 것입니다. 로그 항목을 삭제하려면 DOM에 대해서도 코드를 작성해야합니다. DOM과 별도로 로직을 테스트하는 방법은 무엇입니까? 프레젠테이션을 변경하려면 어떻게해야합니까?
이것은 약간 지저분하고 사소한 연약합니다. 그러나 AngularJS에서는 다음과 같이 할 수 있습니다.
$http( '/myEndpoint.json' ).then( function ( response ) {
$scope.log.push( { msg: 'Data Received!' } );
});
그리고 우리의 견해는 다음과 같습니다.
<ul class="messages">
<li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>
그러나 그 문제에 대해 우리의 견해는 다음과 같을 수 있습니다.
<div class="messages">
<div class="alert" ng-repeat="entry in log">
{{ entry.msg }}
</div>
</div>
이제 정렬되지 않은 목록을 사용하는 대신 Bootstrap 경고 상자를 사용하고 있습니다. 그리고 우리는 컨트롤러 코드를 변경할 필요가 없었습니다! 그러나 더 중요한 것은 로그가 업데이트되는 위치 나 방법에 관계없이보기도 변경된다는 것입니다. 자동으로. 산뜻한!
여기서 보여주지는 않았지만 데이터 바인딩은 양방향입니다. <input ng-model="entry.msg" />
를 수행하여보기에서 편집 할 수도 있습니다. 그리고 많은 기쁨이있었습니다.
고유 모델 레이어
jQuery에서 DOM은 모델과 비슷합니다. 그러나 AngularJS에는 뷰와 완전히 독립적으로 원하는 방식으로 관리 할 수있는 별도의 모델 레이어가 있습니다. 이는 위의 데이터 바인딩에 도움이 되고 우려 사항의 분리를 유지하며 훨씬 더 큰 테스트 가능성을 제공합니다. 다른 답변은이 점을 언급 했으므로 그대로 두겠습니다.
관심사 분리
그리고 위의 모든 내용은이 중요한 주제와 관련이 있습니다. 귀하의 견해는 (대부분의 경우) 일어날 일에 대한 공식적인 기록 역할을합니다. 모델은 데이터를 나타냅니다. 재사용 가능한 작업을 수행 할 서비스 계층이 있습니다. DOM 조작을 수행하고 지시문으로 뷰를 확대합니다. 컨트롤러와 함께 모든 것을 붙입니다. 이것은 다른 답변에서도 언급되었으며 내가 추가 할 유일한 것은 테스트 가능성과 관련이 있으며 아래 다른 섹션에서 논의합니다.
종속성 주입
우려 사항을 분리하는 데 도움이되는 것은 DI (의존성 주입 )입니다. 서버 측 언어 ( Java 에서 PHP로 )에서 온 경우 이미이 개념에 익숙 할 것입니다.하지만 jQuery에서 온 클라이언트 측 사람이라면이 개념은 바보에서 불필요한 것, 힙 스터에 이르기까지 어떤 것이 든 보일 수 있습니다. . 하지만 그렇지 않습니다. :-)
넓은 관점에서 DI는 구성 요소를 매우 자유롭게 선언 한 다음 다른 구성 요소에서 인스턴스를 요청하면 부여 될 수 있음을 의미합니다. 로딩 순서, 파일 위치 또는 이와 유사한 것에 대해 알 필요가 없습니다. 그 힘은 즉시 보이지 않을 수도 있지만, 나는 단지 하나의 (일반적인) 예를 제공 할 것입니다 : 테스트.
애플리케이션에서 REST API를 통해 서버 측 스토리지를 구현하고 애플리케이션 상태에 따라 로컬 스토리지를 구현하는 서비스가 필요하다고 가정 해 보겠습니다. 컨트롤러에서 테스트를 실행할 때 서버와 통신 할 필요가 없습니다. 결국 컨트롤러를 테스트하고 있습니다. 원래 구성 요소와 동일한 이름의 모의 서비스를 추가 할 수 있으며 인젝터는 컨트롤러가 자동으로 가짜 서비스를 얻도록 보장합니다. 컨트롤러는 차이를 알 필요가 없으며 알 필요도 없습니다.
테스트에 대해 말하자면 ...
4. 항상 테스트 중심의 개발
이것은 실제로 아키텍처에 대한 섹션 3의 일부이지만, 너무 중요해서 자체 최상위 섹션으로 넣습니다.
지금까지 보거나 사용했거나 작성한 많은 jQuery 플러그인 중 몇 개에 테스트 스위트가 포함되어 있습니까? jQuery는 그다지 순응하지 않기 때문에 많지 않습니다. 그러나 AngularJS는 있습니다.
jQuery에서 테스트하는 유일한 방법은 테스트가 DOM 조작을 수행 할 수있는 샘플 / 데모 페이지를 사용하여 독립적으로 구성 요소를 만드는 것입니다. 따라서 구성 요소를 별도로 개발 한 다음 응용 프로그램에 통합해야합니다. 얼마나 불편합니다! jQuery로 개발할 때 대부분의 경우 테스트 기반 개발 대신 반복적 인 방식을 선택합니다. 그리고 누가 우리를 비난 할 수 있습니까?
그러나 우려 사항이 분리되어 있기 때문에 AngularJS에서 테스트 기반 개발을 반복적으로 수행 할 수 있습니다! 예를 들어 메뉴에 현재 경로가 무엇인지 나타내는 매우 간단한 지시문이 필요하다고 가정 해 보겠습니다. 애플리케이션의 관점에서 원하는 것을 선언 할 수 있습니다.
<a href="/hello" when-active>Hello</a>
when-active
지시문에 대한 테스트를 작성할 수 있습니다.
it( 'should add "active" when the route changes', inject(function() {
var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );
$location.path('/not-matching');
expect( elm.hasClass('active') ).toBeFalsey();
$location.path( '/hello' );
expect( elm.hasClass('active') ).toBeTruthy();
}));
그리고 테스트를 실행하면 실패 여부를 확인할 수 있습니다. 이제 우리는 지시문을 만들어야합니다.
.directive( 'whenActive', function ( $location ) {
return {
scope: true,
link: function ( scope, element, attrs ) {
scope.$on( '$routeChangeSuccess', function () {
if ( $location.path() == element.attr( 'href' ) ) {
element.addClass( 'active' );
}
else {
element.removeClass( 'active' );
}
});
}
};
});
이제 테스트가 통과 되고 메뉴가 요청 된대로 수행됩니다. 우리의 개발은 반복과 테스트 주도 모두이다. 멋지다.
5. 개념적으로, 지시어는 jQuery 패키지가 아닙니다
"지시문에서 DOM 조작 만 수행"이라는 말을 자주 듣게됩니다. 이것은 필수입니다. 정당한 경의로 대하십시오!
하지만 좀 더 깊이 들어가 보자 ...
일부 지시문은 뷰에 이미있는 것을 장식하기 ngClass
생각하십시오) 때로는 DOM 조작을 즉시 수행 한 다음 기본적으로 수행됩니다. 그러나 지시문이 "위젯"과 같고 템플릿이있는 경우 관심사 분리 도 고려해야합니다. 즉, 템플릿 도 링크 및 컨트롤러 기능의 구현과는 크게 독립적으로 유지되어야합니다.
AngularJS는이 작업을 매우 쉽게 만들어주는 전체 도구 세트와 함께 제공됩니다. ngClass
를 사용하면 클래스를 동적으로 업데이트 할 수 있습니다. ngModel
은 양방향 데이터 바인딩을 허용합니다. ngShow
및 ngHide
프로그래밍 방식으로 요소를 표시하거나 숨 깁니다. 그리고 더 많은 것-우리가 직접 쓰는 것을 포함합니다. 즉, DOM 조작 없이도 모든 종류의 멋진 작업을 수행 할 수 있습니다. DOM 조작이 적을수록 지시문을 테스트하기가 더 쉽고, 스타일을 지정하기가 더 쉽고, 나중에 변경하기가 더 쉬우 며, 재사용 및 배포가 더 쉽습니다.
저는 AngularJS를 처음 접하는 개발자들이 많은 jQuery를 던지는 장소로 지시문을 사용하는 것을 봅니다. 즉, 그들은 "컨트롤러에서 DOM 조작을 할 수 없기 때문에 그 코드를 지시문에 넣을 것"이라고 생각합니다. 확실히 훨씬 낫지 만 여전히 잘못된 경우가 많습니다.
우리는 우리가 지시어에 그것을 넣어 경우에도 3 절에 프로그램 된 로거의 생각, 우리는 여전히 그에게 "각도의 방법"을 수행 할. 여전히 DOM 조작이 필요하지 않습니다! DOM 조작이 필요한 경우가 많지만 생각보다 훨씬 드뭅니다! 응용 프로그램의 어느 곳에서나 DOM 조작을 수행하기 전에 정말로 필요한지 스스로에게 물어보십시오. 더 나은 방법이있을 수 있습니다.
다음은 내가 가장 자주 보는 패턴을 보여주는 간단한 예입니다. 토글 가능한 버튼이 필요합니다. (참고 :이 예제는 정확히 같은 방식으로 해결되는 더 복잡한 경우를 나타 내기 위해 약간 인위적이고 자세한 내용입니다.)
.directive( 'myDirective', function () {
return {
template: '<a class="btn">Toggle me!</a>',
link: function ( scope, element, attrs ) {
var on = false;
$(element).click( function () {
on = !on;
$(element).toggleClass('active', on);
});
}
};
});
이것에 몇 가지 잘못된 점이 있습니다.
- 첫째, jQuery는 필요하지 않았다. JQuery가 필요했던 건 아무것도 없어요!
- 둘째, 페이지에 jQuery가 이미 나와 있더라도 여기서는 사용할 이유가 없습니다. angular.element를 사용하면 jQuery가 없는 프로젝트에 드롭해도 구성 요소는 계속 작동합니다.
- 셋째, 이 지침이 작동하기 위해 jQuery가 필요하다고 가정하더라도 jqLite(angular.element)는 로드된 경우 항상 jQuery를 사용합니다! 따라서 $를 사용할 필요가 없습니다. angular.element만 사용하면 됩니다.
- 넷째, jqLite 요소는 $로 래핑할 필요가 없습니다. 링크 함수에 전달되는 요소는 이미 jQuery 요소가 될 수 있습니다.
- 다섯 번째, 이전 섹션에서 언급했듯이, 우리는 왜 우리의 논리에 템플릿 같은 것들을 섞고 있는 것일까요?
이 지시문은 (매우 복잡한 경우에도!) 훨씬 더 간단하게 다음과 같이 다시 작성할 수 있습니다.
.directive( 'myDirective', function () {
return {
scope: true,
template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
link: function ( scope, element, attrs ) {
scope.on = false;
scope.toggle = function () {
scope.on = !scope.on;
};
}
};
});
다시 말하지만, 템플릿 항목은 템플릿에 있으므로 귀하 (또는 귀하의 사용자)는 필요한 스타일을 충족하는 것으로 쉽게 교체 할 수 있으며 로직 은 건드리지 않아도됩니다. 재사용 성-붐!
그리고 테스트와 같은 다른 모든 이점이 여전히 있습니다. 쉽습니다! 템플릿의 내용에 관계없이 지시문의 내부 API는 건드리지 않으므로 리팩토링이 쉽습니다. 지시문을 건드리지 않고 원하는만큼 템플릿을 변경할 수 있습니다. 그리고 무엇을 변경하더라도 테스트는 통과합니다.
w00t!
따라서 지시문이 jQuery와 유사한 함수의 모음이 아니라면 무엇입니까? 지시어는 실제로 HTML의 확장입니다 . HTML이 필요한 작업을 수행하지 않으면이를 수행하는 지시문을 작성한 다음 HTML의 일부인 것처럼 사용합니다.
ngClick
, AngularJS가 상자 밖에서 무언가를하지 않는다면, 팀이 ngClass
, et al.
요약
jQuery도 사용하지 마십시오. 그것을 포함하지 마십시오. 그것은 당신을 막을 것입니다. 그리고 이미 jQuery에서 해결하는 방법을 알고 있다고 생각하는 문제가 발생하면 $
도달하기 전에 AngularJS 범위 내에서 해결 방법에 대해 생각해보십시오. 모르는 경우 물어보세요! 20 번 중 19 번, 가장 좋은 방법은 jQuery가 필요하지 않으며 jQuery로 해결하려고하면 더 많은 작업을 수행 할 수 있습니다.
출처 : https://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background
'프로그래밍 언어 > jQuery, ajax' 카테고리의 다른 글
사용자가 외부를 클릭 할 때 jQuery를 사용하여 DIV를 숨기는 법. (0) | 2021.07.23 |
---|---|
jQuery를 사용하여 클래스 이름 가져 오기 (0) | 2021.07.22 |
jQuery.fn가 의미하는 것 (0) | 2021.07.20 |
jQuery Event Keypress : 어떤 키를 눌렀는지 찾아내는 방법 (0) | 2021.07.20 |
jQuery를 사용하여 체크 박스에 "선택"설정 (0) | 2021.07.20 |