AngularJS 프레임워크_AngularJS에서 데이터의 양방향 바인딩 적용 분석 예
데이터 바인딩
텍스트 입력 상자를 person.name 속성에 바인딩하여 애플리케이션을 좀 더 흥미롭게 만들 수 있습니다. 이 단계에서는 텍스트 입력 상자와 페이지 사이에 양방향 바인딩을 설정합니다.
이 맥락에서 "양방향"은 뷰가 속성 값을 변경하면 모델이 변경 사항을 "인식"하고, 모델이 속성 값을 변경하면 뷰도 변경 사항을 "인식"한다는 의미입니다. Angular.js는 자동으로 이 메커니즘을 설정합니다. 이것이 어떻게 수행되는지 궁금하신 경우, Digest_loop의 작동을 심도 있게 논의하는 다음 기사를 확인하세요.
이 바인딩을 생성하려면 다음과 같이 텍스트 입력 상자에 ng-model 지시문 속성을 사용합니다.
<div ng-controller="MyController"> <input type="text" ng-model="person.name" placeholder="Enter your name" /> <h5>Hello {{ person.name }}</h5> </div>
이제 데이터 바인딩을 설정했으므로(예, 그만큼 쉽습니다) 뷰가 모델을 어떻게 변경하는지 살펴보겠습니다.
해 보세요:
텍스트 상자에 입력하면 아래 이름도 자동으로 변경됩니다. 이는 뷰에서 모델로의 데이터 바인딩 방향을 보여줍니다.
또한 (클라이언트) 백엔드에서 모델을 변경할 수 있으며 이 변경 사항이 프런트 엔드에 자동으로 반영되는 것을 확인할 수 있습니다. 이 프로세스를 보여주기 위해 MyController 모델에 $scope의 데이터를 업데이트하는 타이머 함수를 작성해 보겠습니다. 다음 코드에서는 매초(시계처럼) 시간을 측정하고 $scope에서 시계 변수 데이터를 업데이트하는 타이머 함수를 만듭니다.
app.controller('MyController', function($scope) { $scope.person = { name: "Ari Lerner" }; var updateClock = function() { $scope.clock = new Date(); }; var timer = setInterval(function() { $scope.$apply(updateClock); }, 1000); updateClock(); });
보시다시피 모델에서 시계 변수의 데이터를 변경하면 뷰가 자동으로 업데이트되어 이 변경 사항을 반영합니다. 중괄호를 사용하면 뷰에 시계 변수의 값을 쉽게 표시할 수 있습니다.
<div ng-controller="MyController"> <h5>{{ clock }}</h5> </div>
상호작용
앞서 우리는 데이터를 텍스트 입력 상자에 바인딩했습니다. 데이터 바인딩은 데이터에만 국한되지 않으며 바인딩을 사용하여 $scope에서 함수를 호출할 수도 있습니다(이것은 이전에 언급했습니다).
버튼, 링크 또는 기타 DOM 요소의 경우 다른 지시어 속성을 사용하여 바인딩을 구현할 수 있습니다: ng-click. 이 ng-click 지시문은 DOM 요소의 마우스 클릭 이벤트(예: mousedown 브라우저 이벤트)를 메서드에 바인딩합니다. 브라우저가 DOM 요소에서 마우스로 클릭 이벤트를 트리거하면 바인딩된 메서드가 호출됩니다. 이전 예와 유사하게 이 바인딩의 코드는 다음과 같습니다.
<div ng-controller="DemoController"> <h4>The simplest adding machine ever</h4> <button ng-click="add(1)" class="button">Add</button> <button ng-click="subtract(1)" class="button">Subtract</button> <h4>Current count: {{ counter }}</h4> </div>
두 버튼과 링크는 모두 해당 DOM 요소를 포함하는 컨트롤러가 소유한 $scope 객체에 바인딩됩니다. 마우스로 클릭하면 Angular가 해당 메서드를 호출합니다. Angular에게 어떤 메서드를 호출할지 알려줄 때 메서드 이름을 따옴표로 묶은 문자열에 씁니다.
app.controller('DemoController', function($scope) { $scope.counter = 0; $scope.add = function(amount) { $scope.counter += amount; }; $scope.subtract = function(amount) { $scope.counter -= amount; }; });
참고하세요:
$scope.$watch
$scope.$watch( watchExp, listener, objectEquality );
변수의 변경 사항을 모니터링하려면 $scope.$watch 함수를 사용할 수 있습니다. 이 함수에는 "관찰할 대상"(watchExp), "변경 시 발생하는 작업"(리스너) 및 변수를 감시할지 또는 객체를 감시할지 여부를 지정하는 세 가지 매개 변수가 있습니다. 하나의 매개변수를 확인할 때 세 번째 매개변수는 무시할 수 있습니다. 예를 들면 다음과 같습니다.
$scope.name = 'Ryan'; $scope.$watch( function( ) { return $scope.name; }, function( newValue, oldValue ) { console.log('$scope.name was updated!'); } );
AngularJS는 $scope에 감시 기능을 등록합니다. $scope에 등록된 항목을 보려면 콘솔에 $scope를 출력하면 됩니다.
$scope.name이 변경된 것을 콘솔에서 볼 수 있습니다. 이는 $scope.name의 이전 값이 정의되지 않은 것처럼 보였고 이제 이를 Ryan에게 할당하기 때문입니다!
$wach의 첫 번째 매개변수에는 문자열을 사용할 수도 있습니다. 이는 기능을 제공하는 것과 똑같습니다. AngularJS 소스 코드에서 볼 수 있듯이 문자열을 사용하면 다음 코드가 실행됩니다.
if (typeof watchExp == 'string' && get.constant) { var originalFn = watcher.fn; watcher.fn = function(newVal, oldVal, scope) { originalFn.call(this, newVal, oldVal, scope); arrayRemove(array, watcher); }; }
이렇게 하면 watchExp가 함수로 설정되며, 이름을 지정한 범위의 변수도 자동으로 반환됩니다.
$$감시자
$scope의 $$watchers 변수는 우리가 정의한 모든 모니터를 저장합니다. 콘솔에서 $$watchers를 보면 객체의 배열임을 알 수 있습니다.
$$watchers = [ { eq: false, // 表明我们是否需要检查对象级别的相等 fn: function( newValue, oldValue ) {}, // 这是我们提供的监听器函数 last: 'Ryan', // 变量的最新值 exp: function(){}, // 我们提供的watchExp函数 get: function(){} // Angular's编译后的watchExp函数 } ];
$watch函数将会返回一个deregisterWatch函数。这意味着如果我们使用$scope.$watch对一个变量进行监视,我们也可以在以后通过调用某个函数来停止监视。
$scope.$apply
当一个控制器/指令/等等东西在AngularJS中运行时,AngularJS内部会运行一个叫做$scope.$apply的函数。这个$apply函数会接收一个函数作为参数并运行它,在这之后才会在rootScope上运行$digest函数。
AngularJS的$apply函数代码如下所示:
$apply: function(expr) { try { beginPhase('$apply'); return this.$eval(expr); } catch (e) { $exceptionHandler(e); } finally { clearPhase(); try { $rootScope.$digest(); } catch (e) { $exceptionHandler(e); throw e; } } }
上面代码中的expr参数就是你在调用$scope.$apply()时传递的参数 – 但是大多数时候你可能都不会去使用$apply这个函数,要用的时候记得给它传递一个参数。
下面我们来看看ng-keydown是怎么来使用$scope.$apply的。为了注册这个指令,AngularJS会使用下面的代码。
var ngEventDirectives = {}; forEach( 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '), function(name) { var directiveName = directiveNormalize('ng-' + name); ngEventDirectives[directiveName] = ['$parse', function($parse) { return { compile: function($element, attr) { var fn = $parse(attr[directiveName]); return function ngEventHandler(scope, element) { element.on(lowercase(name), function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); }; } }; }]; } );
上面的代码做的事情是循环了不同的类型的事件,这些事件在之后可能会被触发并创建一个叫做ng-[某个事件]的新指令。在指令的compile函数中,它在元素上注册了一个事件处理器,它和指令的名字一一对应。当事件被出发时,AngularJS就会运行scope.$apply函数,并让它运行一个函数。
只是单向数据绑定吗?
上面所说的ng-keydown只能够改变和元素值相关联的$scope中的值 – 这只是单项数据绑定。这也是这个指令叫做ng-keydown的原因,只有在keydown事件被触发时,能够给与我们一个新值。
但是我们想要的是双向数据绑定!
我们现在来看一看ng-model。当你在使用ng-model时,你可以使用双向数据绑定 – 这正是我们想要的。AngularJS使用$scope.$watch(视图到模型)以及$scope.$apply(模型到视图)来实现这个功能。
ng-model会把事件处理指令(例如keydown)绑定到我们运用的输入元素上 – 这就是$scope.$apply被调用的地方!而$scope.$watch是在指令的控制器中被调用的。你可以在下面代码中看到这一点:
$scope.$watch(function ngModelWatch() { var value = ngModelGet($scope); //如果作用域模型值和ngModel值没有同步 if (ctrl.$modelValue !== value) { var formatters = ctrl.$formatters, idx = formatters.length; ctrl.$modelValue = value; while(idx--) { value = formatters[idx](value); } if (ctrl.$viewValue !== value) { ctrl.$viewValue = value; ctrl.$render(); } } return value; });
如果你在调用$scope.$watch时只为它传递了一个参数,无论作用域中的什么东西发生了变化,这个函数都会被调用。在ng-model中,这个函数被用来检查模型和视图有没有同步,如果没有同步,它将会使用新值来更新模型数据。这个函数会返回一个新值,当它在$digest函数中运行时,我们就会知道这个值是什么!
为什么我们的监听器没有被触发?
如果我们在$scope.$watch的监听器函数中停止这个监听,即使我们更新了$scope.name,该监听器也不会被触发。
正如前面所提到的,AngularJS将会在每一个指令的控制器函数中运行$scope.$apply。如果我们查看$scope.$apply函数的代码,我们会发现它只会在控制器函数已经开始被调用之后才会运行$digest函数 – 这意味着如果我们马上停止监听,$scope.$watch函数甚至都不会被调用!但是它究竟是怎样运行的呢?
$digest函数将会在$rootScope中被$scope.$apply所调用。它将会在$rootScope中运行digest循环,然后向下遍历每一个作用域并在每个作用域上运行循环。在简单的情形中,digest循环将会触发所有位于$$watchers变量中的所有watchExp函数,将它们和最新的值进行对比,如果值不相同,就会触发监听器。
当digest循环运行时,它将会遍历所有的监听器然后再次循环,只要这次循环发现了”脏值”,循环就会继续下去。如果watchExp的值和最新的值不相同,那么这次循环就会被认为发现了脏值。理想情况下它会运行一次,如果它运行超10次,你会看到一个错误。
因此当$scope.$apply运行的时候,$digest也会运行,它将会循环遍历$$watchers,只要发现watchExp和最新的值不相等,变化触发事件监听器。在AngularJS中,只要一个模型的值可能发生变化,$scope.$apply就会运行。这就是为什么当你在AngularJS之外更新$scope时,例如在一个setTimeout函数中,你需要手动去运行$scope.$apply():这能够让AngularJS意识到它的作用域发生了变化。
创建自己的脏值检查
到此为止,我们已经可以来创建一个小巧的,简化版本的脏值检查了。当然,相比较之下,AngularJS中实现的脏值检查要更加先进一些,它提供疯了异步队列以及其他一些高级功能。
设置Scope
Scope仅仅只是一个函数,它其中包含任何我们想要存储的对象。我们可以扩展这个函数的原型对象来复制$digest和$watch。我们不需要$apply方法,因为我们不需要在作用域的上下文中执行任何函数 – 我们只需要简单的使用$digest。我们的Scope的代码如下所示:
var Scope = function( ) { this.$$watchers = []; }; Scope.prototype.$watch = function( ) { }; Scope.prototype.$digest = function( ) { };
我们的$watch函数需要接受两个参数,watchExp和listener。当$watch被调用时,我们需要将它们push进入到Scope的$$watcher数组中。
var Scope = function( ) { this.$$watchers = []; }; Scope.prototype.$watch = function( watchExp, listener ) { this.$$watchers.push( { watchExp: watchExp, listener: listener || function() {} } ); }; Scope.prototype.$digest = function( ) { };
你可能已经注意到了,如果没有提供listener,我们会将listener设置为一个空函数 – 这样一来我们可以$watch所有的变量。
接下来我们将会创建$digest。我们需要来检查旧值是否等于新的值,如果二者不相等,监听器就会被触发。我们会一直循环这个过程,直到二者相等。这就是”脏值”的来源 – 脏值意味着新的值和旧的值不相等!
var Scope = function( ) { this.$$watchers = []; }; Scope.prototype.$watch = function( watchExp, listener ) { this.$$watchers.push( { watchExp: watchExp, listener: listener || function() {} } ); }; Scope.prototype.$digest = function( ) { var dirty; do { dirty = false; for( var i = 0; i < this.$$watchers.length; i++ ) { var newValue = this.$$watchers[i].watchExp(), oldValue = this.$$watchers[i].last; if( oldValue !== newValue ) { this.$$watchers[i].listener(newValue, oldValue); dirty = true; this.$$watchers[i].last = newValue; } } } while(dirty); };
接下来,我们将创建一个作用域的实例。我们将这个实例赋值给$scope。我们接着会注册一个监听函数,在更新$scope之后运行$digest!
var Scope = function( ) { this.$$watchers = []; }; Scope.prototype.$watch = function( watchExp, listener ) { this.$$watchers.push( { watchExp: watchExp, listener: listener || function() {} } ); }; Scope.prototype.$digest = function( ) { var dirty; do { dirty = false; for( var i = 0; i < this.$$watchers.length; i++ ) { var newValue = this.$$watchers[i].watchExp(), oldValue = this.$$watchers[i].last; if( oldValue !== newValue ) { this.$$watchers[i].listener(newValue, oldValue); dirty = true; this.$$watchers[i].last = newValue; } } } while(dirty); }; var $scope = new Scope(); $scope.name = 'Ryan'; $scope.$watch(function(){ return $scope.name; }, function( newValue, oldValue ) { console.log(newValue, oldValue); } ); $scope.$digest();
成功了!我们现在已经实现了脏值检查(虽然这是最简单的形式)!上述代码将会在控制台中输出下面的内容:
Ryan undefined
这正是我们想要的结果 – $scope.name之前的值是undefined,而现在的值是Ryan。
现在我们把$digest函数绑定到一个input元素的keyup事件上。这就意味着我们不需要自己去调用$digest。这也意味着我们现在可以实现双向数据绑定!
var Scope = function( ) { this.$$watchers = []; }; Scope.prototype.$watch = function( watchExp, listener ) { this.$$watchers.push( { watchExp: watchExp, listener: listener || function() {} } ); }; Scope.prototype.$digest = function( ) { var dirty; do { dirty = false; for( var i = 0; i < this.$$watchers.length; i++ ) { var newValue = this.$$watchers[i].watchExp(), oldValue = this.$$watchers[i].last; if( oldValue !== newValue ) { this.$$watchers[i].listener(newValue, oldValue); dirty = true; this.$$watchers[i].last = newValue; } } } while(dirty); }; var $scope = new Scope(); $scope.name = 'Ryan'; var element = document.querySelectorAll('input'); element[0].onkeyup = function() { $scope.name = element[0].value; $scope.$digest(); }; $scope.$watch(function(){ return $scope.name; }, function( newValue, oldValue ) { console.log('Input value updated - it is now ' + newValue); element[0].value = $scope.name; } ); var updateScopeValue = function updateScopeValue( ) { $scope.name = 'Bob'; $scope.$digest(); };
使用上面的代码,无论何时我们改变了input的值,$scope中的name属性都会相应的发生变化。这就是隐藏在AngularJS神秘外衣之下数据双向绑定的秘密!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

얼굴 검출 및 인식 기술은 이미 상대적으로 성숙하고 널리 사용되는 기술입니다. 현재 가장 널리 사용되는 인터넷 응용 언어는 JS입니다. 웹 프런트엔드에서 얼굴 감지 및 인식을 구현하는 것은 백엔드 얼굴 인식에 비해 장점과 단점이 있습니다. 장점에는 네트워크 상호 작용 및 실시간 인식이 줄어 사용자 대기 시간이 크게 단축되고 사용자 경험이 향상된다는 단점이 있습니다. 모델 크기에 따라 제한되고 정확도도 제한됩니다. js를 사용하여 웹에서 얼굴 인식을 구현하는 방법은 무엇입니까? 웹에서 얼굴 인식을 구현하려면 JavaScript, HTML, CSS, WebRTC 등 관련 프로그래밍 언어 및 기술에 익숙해야 합니다. 동시에 관련 컴퓨터 비전 및 인공지능 기술도 마스터해야 합니다. 웹 측면의 디자인으로 인해 주목할 가치가 있습니다.

Angular.js는 동적 애플리케이션을 만들기 위해 자유롭게 액세스할 수 있는 JavaScript 플랫폼입니다. HTML 구문을 템플릿 언어로 확장하여 애플리케이션의 다양한 측면을 빠르고 명확하게 표현할 수 있습니다. Angular.js는 코드를 작성, 업데이트 및 테스트하는 데 도움이 되는 다양한 도구를 제공합니다. 또한 라우팅 및 양식 관리와 같은 많은 기능을 제공합니다. 이 가이드에서는 Ubuntu24에 Angular를 설치하는 방법에 대해 설명합니다. 먼저 Node.js를 설치해야 합니다. Node.js는 서버 측에서 JavaScript 코드를 실행할 수 있게 해주는 ChromeV8 엔진 기반의 JavaScript 실행 환경입니다. Ub에 있으려면

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

주식 분석을 위한 필수 도구: PHP 및 JS에서 캔들 차트를 그리는 단계를 배우십시오. 인터넷과 기술의 급속한 발전으로 주식 거래는 많은 투자자에게 중요한 방법 중 하나가 되었습니다. 주식분석은 투자자의 의사결정에 있어 중요한 부분이며 캔들차트는 기술적 분석에 널리 사용됩니다. PHP와 JS를 사용하여 캔들 차트를 그리는 방법을 배우면 투자자가 더 나은 결정을 내리는 데 도움이 되는 보다 직관적인 정보를 얻을 수 있습니다. 캔들스틱 차트는 주가를 캔들스틱 형태로 표시하는 기술 차트입니다. 주가를 보여주네요

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 소개: 인터넷의 대중화와 기술의 발전으로 점점 더 많은 레스토랑에서 온라인 주문 서비스를 제공하기 시작했습니다. 실시간 온라인 주문 시스템을 구현하기 위해 JavaScript 및 WebSocket 기술을 사용할 수 있습니다. WebSocket은 TCP 프로토콜을 기반으로 하는 전이중 통신 프로토콜로 클라이언트와 서버 간의 실시간 양방향 통신을 실현할 수 있습니다. 실시간 온라인 주문 시스템에서는 사용자가 요리를 선택하고 주문을 하면

인터넷 금융의 급속한 발전으로 인해 주식 투자는 점점 더 많은 사람들의 선택이 되었습니다. 주식 거래에서 캔들 차트는 주가의 변화 추세를 보여주고 투자자가 보다 정확한 결정을 내리는 데 도움이 되는 일반적으로 사용되는 기술적 분석 방법입니다. 이 기사에서는 PHP와 JS의 개발 기술을 소개하고 독자가 주식 캔들 차트를 그리는 방법을 이해하도록 유도하며 구체적인 코드 예제를 제공합니다. 1. 주식 캔들 차트의 이해 주식 캔들 차트를 그리는 방법을 소개하기 전에 먼저 캔들 차트가 무엇인지부터 이해해야 합니다. 캔들스틱 차트는 일본인이 개발했습니다.

Angular 프레임워크의 구성 요소에 대한 기본 표시 동작은 블록 수준 요소에 대한 것이 아닙니다. 이 디자인 선택은 구성 요소 스타일의 캡슐화를 촉진하고 개발자가 각 구성 요소가 표시되는 방법을 의식적으로 정의하도록 장려합니다. CSS 속성 표시를 명시적으로 설정하면 Angular 구성 요소의 표시를 완전히 제어하여 원하는 레이아웃과 응답성을 얻을 수 있습니다.
