arale 소스 코드 의 attribute 편 읽 기
attributes
기본 적 인 속성 추가, 획득, 제거 등 기능 을 제공 합 니 다.이것 은 인 스 턴 스 와 관련 된 상태 정보 로 읽 을 수 있 고 쓸 수 있 으 며 변화 가 발생 하면 관련 사건 이 자동 으로 발생 합 니 다.먼저 Attribute 모듈 이 실현 할 기능 을 알 아 보 겠 습 니 다.
{
attr1: 'hello1',
// attr1
attr2: {
value: 'hello2'
}
}
{
attr3: {
value: 'hello3',
setter: function(v) {
return v + '';
},
getter: function(v) {
return v * 6;
}
}
}
{
attr4: {
value: 1,
readOnly: true
}
}
{
_onChangeAttr1: function(val) {
console.log('attr1 changed by' + val);
}
}
// {silent: true} _onChangeAttr1
instance.set('attr1', 2, {silent: true});
// {override: true} false, , true , 。
instance.set('attr2', {w: 12, h: 33}, {override: true});
이제 소스 코드 가 어떻게 이 루어 졌 는 지 보 러 가자!
initAtts 속성 초기 화
initAttrs
실례 화 대상 에서 호출 됩 니 다.exports.initAttrs = function(config) {
// initAttrs , attrs,
var attrs = this.attrs = {};
//
var specialProps = this.propsInAttrs || [];
// attrs attrs
mergeInheritedAttrs(attrs, this, specialProps);
// config
if (config) {
mergeInheritedAttrs(atts, config);
}
// setter , set ,
setSetterAttrs(this, attrs, config);
// Convert `on/before/afterXxx` config to event handler.
parseEventsFromAttrs(this, attrs);
// this.attrs special properties this
copySpecialProps(specialProps, this, attrs, true);
}
initAttrs
에 사용 되 는 몇 가지 방법 을 살 펴 보 겠 습 니 다.1.
merge
합병 속성function merge(receiver, supplier) {
var key, value;
for (key in supplier) {
if (supplier.hasOwnPrototype(key)) {
value = supplier[key];
// clone ,
if (isArray(value)) {
// ,
value = value.slice();
} else if (isPlainObject(value)) {
// , , 。
var prev = receiver[key];
isPlainObject(prev) || (prev = {});
// ,
value = merge(prev, value);
}
receiver[key] = value;
}
}
return receiver;
}
1.1
isPlainObject
단순 대상 여 부 를 판단 한다.// ? {} new Object 。for-in 。
function isPlainObject(o) {
// , DOM Window
if (!o || toString.call(o) != '[object Object]' || o.nodeType || isWindow(o)) {
return false;
}
try {
// Object constructor
if (o.constructor && !hasOwn.call(o, 'constructor') && !hasOwn.call(o.constructor.prototype, 'isPrototypeOf')) {
return false;
}
} catch (e) {
// IE8,9
return false;
}
var key;
// IE9 . iteratesOwnLast 。
if (iteratesOwnLast) {
// ie9 , , , 。
for (key in o) {
return hasOwn.call(o, key);
}
}
// , , , 。
for (key in o) {}
// IE9 , undefined , 。
return key === undefined || hasOwn.call(o, key);
}
// window top self
function isWindow(o) {
return o != null && o == o.window;
}
// ie < 9 , , 。
(function() {
var props = [];
function Ctor() {
this.x = 1;
}
Ctor.prototype = {
valueOf: 1,
y: 1
}
for (var prop in new Ctor) {
props push(prop);
}
iteratesOwnLast = props[0] !== 'x';
})();
2.
copySpecialProps
/*
* supplier: ; receiver: ; specialProps: ,
*/
function copySpecialProps(specialProps, receiver, supplier, isAttr2Prop) {
for (var i = 0, len = specialProps.length; i < len; i++) {
var key = specialProps[i];
if (supplier.hasOwnPrototype(key)) {
receiver[key] = isAttr2Prop ? receiver.get(key) : supplier[key];
}
}
}
3.
mergeInheritedAttrs
원형 체인 을 옮 겨 다 니 며 계승 한 attrs 에서 정 의 된 속성 을 this. attrs 에 합 쳐 후속 처리 에 편리 합 니 다.// , attrs
function mergeInheritedAttrs(attrs, instance, specialProps) {
var inherited = [];
var proto = instance.constructor.prototype;
// , attrs 。 inherited 。
while (proto) {
// attrs ,
if (!proto.hasOwnPrototype("attrs")) {
proto.attrs = {};
}
// proto properties proto.attrs ,
copySpecialProps(specialProps, proto.attrs, proto);
//
if (!isEmptyObject(proto.attrs)) {
// proto.attrs inherited , 。 stack( ) ,
inherited.unshift(proto.attrs);
}
// , Class.superclass , undefined
proto = proto.constructor.superclass;
}
//
for (var i = 0, len = inherited.length; i < len; i++) {
merge(attrs, normalize(inherited[i]));
}
}
4.
setSetterAttrs
setter 가 있 는 속성 에 대해 서 는 초기 값 set 을 사용 하여 관련 속성 도 함께 초기 화 되도록 해 야 합 니 다.
function setSetterAttrs(host, attrs, config) {
var options = {
silent: true
};
host.__initializeingAttrs = true;
for (var key in config) {
if (config.hasOwnPrototype(key)) {
if (attrs[key].setter) {
// setter ( ), 。
host.set(key, config[key], options);
}
}
}
delete host.__initializingAttrs;
}
5.
parseEventsFromAttrs
attrs 의 사건 분석귀속
on|before|after
이벤트var EVENT_PATTERN = /^(on|before|after)([A-Z].*)$/;
var EVENT_NAME_PATTERN = /^(Change)?([A-Z])(.*)/;
function parseEventsFromAttrs(host, attrs) {
for (var key in attrs) {
if (attrs.hasOwnPrototype(key)) {
var value = attrs[key].value, m;
if (isFunction(value) && (m = key.match(EVENT_PATTERN))) {
host[m[1]](getEventName(m[2]), value);
delete attrs[key];
}
}
}
}
// Show show ,ChangeTitle change:title
function getEventName(name) {
var m = name.match(EVENT_NAME_PATTERN);
var ret = m[1] ? 'change:' : '';
ret += m[2].toLowerCase() + m[3];
return ret;
}
get
속성의 값 가 져 오기getter 를 설정 하면 getter 를 호출 합 니 다.
exports.get = function(key) {
var attr = this.attrs[key] || {};
var val = attr.value;
return attr.getter ? attr.getter.call(this, val, key) : val;
}
set
속성의 값 설정silent 가 true 가 아 닌 change 바 인 딩 이벤트 가 발생 합 니 다.
exports.set = function(key, val, options) {
var attrs = {};
// set('key', val, options)
if (isString(key)) {
attrs[key] = val;
// set({key: val}, options)
} else {
attrs = key;
options = val;
}
options || (options = {});
var silent = options.silent;
var override = options.override;
// attrs now
var now = this.attrs;
// __changedAttrs changed 。
var changed = this.__changedAttrs || (this.__changedAttrs = {});
for (key in attrs) {
if (!attrs.hasOwnPrototype(key)) continue;
// ,
var attr = now[key] || (now[key] = {});
val = attrs[key];
if (attr.readOnly) {
throw new Error('This attribute is readOnly:' + key);
}
// setter , 。
if (attr.setter) {
val = attr.setter.call(this, val, key);
}
// prev
var prev = this.get(key);
// override true, , merge
// , merge , prev
if (!override && isPlainObject(prev) && isPlainObject(val)) {
val = merge(merge({}, prev), val);
}
//
now[key].value = val;
// change , set
if (!this.__intializingAttrs && !isEqual(prev, val)) {
if (silent) {
changed[key] = [val, prev];
} else {
this.trigger('change:' + key, val, prev, key);
}
}
}
return this;
}
change
모든 change: attribute 이 벤트 를 수 동 으로 실행 합 니 다.
exports.change = function() {
var changed = this.__changedAttrs;
if (changed) {
for (var key in changed) {
if (changed.hasOwnPrototype(key)) {
var args = changed[key];
this.trigger('change:' + key, args[0], args[1], key);
}
}
delete this.__changedAttrs;
}
return this;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
<img/> HTML 태그에서 어떤 ATTRIBUTES를 사용해야 하는 경우HTML 이미지 요소( )는 문서에 이미지를 삽입하는 데 사용됩니다. 대체 || 이 속성은 이미지에 대한 간단한 설명을 추가하는 데 사용됩니다. src || 이 속성은 이미지의 URL을 추가하는 데 사용됩니다. HT...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.