[ 
https://issues.apache.org/jira/browse/WEEX-577?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16588730#comment-16588730
 ] 

ASF GitHub Bot commented on WEEX-577:
-------------------------------------

cxfeng1 closed pull request #1453: [WEEX-577][iOS] refactoring recycle list's 
data structure and bug-fix
URL: https://github.com/apache/incubator-weex/pull/1453
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm 
b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm
index 53db417de6..340b139c30 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.mm
@@ -57,7 +57,7 @@ - (void)updateCellData:(NSDictionary *)data
 {
     WXAssertComponentThread();
     [self updateBindingData:data];
-    [self _attachSlotEvent:data];
+    [self attachSlotEvent:data];
     [self triggerLayout];
 }
 
diff --git 
a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm 
b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
index e29f288c1d..dccc0d2109 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
@@ -90,41 +90,47 @@ - (void)updateBindingData:(NSDictionary *)data
     }
     
     __block NSMutableDictionary *newData = [NSMutableDictionary dictionary];
-    [templateComponent->_bindingProps 
enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, WXDataBindingBlock 
 _Nonnull block, BOOL * _Nonnull stop) {
-        BOOL needUpdate;
-        id value = block(data, &needUpdate);
-        if (value) {
-            newData[key] = value;
-        }
-    }];
+    if (templateComponent->_bindingProps) {
+        [templateComponent->_bindingProps 
enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, WXDataBindingBlock 
 _Nonnull block, BOOL * _Nonnull stop) {
+            BOOL needUpdate;
+            id value = block(data, &needUpdate);
+            if (value) {
+                newData[key] = value;
+            }
+        }];
+    }
     
     if (self.attributes[@"@isComponentRoot"]) {
-        if (![recycleListComponent.dataManager 
virtualComponentDataWithIndexPath:indexPath]) {
+        NSString *templateId = self.attributes[@"@templateId"];
+        if (![recycleListComponent.dataManager 
virtualComponentDataWithIndexPath:indexPath templateId:templateId]) {
             static NSUInteger __componentId = 0;
-            self->_virtualComponentId = [NSString stringWithFormat:@"%@@%lu", 
listRef, (unsigned long)__componentId % (2048*1024)];
+            self->_virtualComponentId = [NSString 
stringWithFormat:@"%@@%lu*%@", listRef, (unsigned long)__componentId % 
(2048*1024),templateId];
             __componentId++;
             dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
-            [[WXSDKManager bridgeMgr] 
callComponentHook:self.weexInstance.instanceId 
componentId:self.attributes[@"@templateId"] type:@"lifecycle" hook:@"create" 
args:@[self->_virtualComponentId, newData] competion:^(JSValue *value) {
-                [newData addEntriesFromDictionary:[value toArray][0]];
+            [[WXSDKManager bridgeMgr] 
callComponentHook:self.weexInstance.instanceId componentId:templateId 
type:@"lifecycle" hook:@"create" args:@[self->_virtualComponentId, newData] 
competion:^(JSValue *value) {
                 [newData setObject:indexPath forKey:@"indexPath"];
                 [newData setObject:listRef forKey:@"recycleListComponentRef"];
-                [[recycleListComponent dataManager] 
updateVirtualComponentData:self->_virtualComponentId data:newData];
+                if ([[value toArray][0] isKindOfClass:[NSDictionary class]]) {
+                    NSMutableDictionary *virtualComponentData = [value 
toArray][0];
+                    [virtualComponentData setObject:indexPath 
forKey:@"indexPath"];
+                    [[recycleListComponent dataManager] 
updateVirtualComponentData:self->_virtualComponentId data:virtualComponentData];
+                    [newData addEntriesFromDictionary:virtualComponentData];
+                }
                 dispatch_semaphore_signal(semaphore);
             }];
             dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
             
             [self _refsConventFromData:newData];
-            NSIndexPath *indexPath = newData[@"item"][@"indexPath"];
-            NSUInteger position = [indexPath indexAtPosition:1];
-            [[WXSDKManager bridgeMgr] 
callComponentHook:self.weexInstance.instanceId 
componentId:self->_virtualComponentId type:@"lifecycle" hook:@"attach" 
args:@[@{@"virtualComponentId":self->_virtualComponentId,@"position":@(position),@"refs":self->_virtalElementInfo[@"refs"]?:@{}}]
 competion:nil];
+            [[WXSDKManager bridgeMgr] 
callComponentHook:self.weexInstance.instanceId 
componentId:self->_virtualComponentId type:@"lifecycle" hook:@"attach" 
args:@[@{@"virtualComponentId":self->_virtualComponentId,@"position":@(indexPath.row),@"refs":self->_virtualElementInfo[@"refs"]?:@{}}]
 competion:nil];
             if ([newData count]) {
                 data = newData;
             }
         } else {
-            newData[@"componentDataId"] = self->_virtualComponentId;
-            NSDictionary * virtualComponentData = 
[recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath];
+            NSDictionary *virtualComponentData = 
[recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath 
templateId:templateId];
             [newData addEntriesFromDictionary:virtualComponentData];
-            [newData addEntriesFromDictionary:data];
+            newData[@"virtualComponentId"] = self->_virtualComponentId;
+            [newData setObject:indexPath forKey:@"indexPath"];
+            [newData setObject:listRef forKey:@"recycleListComponentRef"];
             data = newData;
         }
     }
@@ -312,7 +318,6 @@ - (void)_storeBindings:(NSDictionary 
*)stylesOrAttributesOrEvents type:(WXDataBi
             WXAssert(NO, @"error binding type:%z", type);
             break;
     }
-    
     [stylesOrAttributesOrEvents enumerateKeysAndObjectsUsingBlock:^(id  
_Nonnull name, id  _Nonnull binding, BOOL * _Nonnull stop) {
         if ([binding isKindOfClass:[NSDictionary class]] && 
binding[WXBindingIdentify]) {
             // {"attributeOrStyleName":{"@binding":"bindingExpression"}
@@ -351,7 +356,6 @@ - (void)_storeBindings:(NSDictionary 
*)stylesOrAttributesOrEvents type:(WXDataBi
                         }
                     }
                 }];
-                
                 return type == WXDataBindingTypeEvents ? newArray : [newArray 
componentsJoinedByString:@""];
             };
         }
@@ -399,7 +403,8 @@ - 
(WXDataBindingBlock)bindingBlockWithExpression:(WXJSExpression *)expression
                 return data[identiferName];
             } else {
                 WXLogError(@"identifer:%@ not found", identiferName);
-                return nil;
+                *needUpdate = YES;
+                return @"";
             }
         } else if (expression->is<WXJSMemberExpression>()) {
             WXJSMemberExpression *member = (WXJSMemberExpression *)expression;
@@ -418,7 +423,9 @@ - 
(WXDataBindingBlock)bindingBlockWithExpression:(WXJSExpression *)expression
                 if (memberExpression->is<WXJSIdentifier>()) {
                     NSString *propertyName = [NSString 
stringWithCString:(((WXJSStringLiteral *)member->property)->value).c_str() 
encoding:[NSString defaultCStringEncoding]];
                     *needUpdate = objectNeedUpdate;
-                    return object[propertyName];
+                    if ([object isKindOfClass:[NSDictionary class]]) {
+                        return object[propertyName];
+                    }
                 } else {
                     id retvalue = [self 
bindingBlockWithExpression:member->property](object, &objectNeedUpdate);
                     *needUpdate = objectNeedUpdate || propertyNeedUpdate;
@@ -534,31 +541,37 @@ - 
(WXDataBindingBlock)bindingBlockWithExpression:(WXJSExpression *)expression
     return block;
 }
 
-- (void)_attachSlotEvent:(NSDictionary *)data
+- (void)attachSlotEvent:(NSDictionary *)data
 {
-    [self _refsConventFromData:data];
-    if (_virtalElementInfo.count != 0) {
-        NSIndexPath *indexPath = data[@"item"][@"indexPath"];
-        NSUInteger position = [indexPath indexAtPosition:1];
-        [_virtalElementInfo 
addEntriesFromDictionary:@{@"position":@(position)}];
-        [[WXSDKManager bridgeMgr] fireEvent:self.weexInstance.instanceId 
ref:data[@"item"][@"recycleListComponentRef"] type:@"_attach_slot" 
params:_virtalElementInfo domChanges:nil handlerArguments:nil];
-    }
+    [self cellSlotEventHandle:data isAttach:YES];
+}
+
+- (void)detachSlotEvent:(NSDictionary *)data
+{
+    [self cellSlotEventHandle:data isAttach:NO];
 }
 
-- (void)_detachSlotEvent:(NSDictionary *)data
+- (void)cellSlotEventHandle:(NSDictionary *)data isAttach:(BOOL)isAttach
 {
     [self _refsConventFromData:data];
-    if (_virtalElementInfo.count != 0) {
-        NSIndexPath *indexPath = data[@"item"][@"indexPath"];
-        NSUInteger position = [indexPath indexAtPosition:1];
-        [_virtalElementInfo 
addEntriesFromDictionary:@{@"position":@(position)}];
-        [[WXSDKManager bridgeMgr] fireEvent:self.weexInstance.instanceId 
ref:data[@"item"][@"recycleListComponentRef"] type:@"_detach_slot" 
params:_virtalElementInfo domChanges:nil handlerArguments:nil];
+    if (_virtualElementInfo.count != 0) {
+        NSString *recycleListComponentRef = data[@"recycleListComponentRef"];
+        NSIndexPath *indexPath = data[@"indexPath"];
+        if (!recycleListComponentRef) {
+            if (data[@"aliasKey"]) {
+                id key = data[@"aliasKey"];
+                recycleListComponentRef = 
data[key][@"recycleListComponentRef"];
+                indexPath = data[key][@"indexPath"];
+            }
+        }
+        [_virtualElementInfo 
addEntriesFromDictionary:@{@"position":@(indexPath.row)}];
+        [[WXSDKManager bridgeMgr] fireEvent:self.weexInstance.instanceId 
ref:recycleListComponentRef type:isAttach ?@"_attach_slot": @"_detach_slot" 
params:_virtualElementInfo domChanges:nil handlerArguments:nil];
     }
 }
 
 - (void )_refsConventFromData:(NSDictionary *)data
 {
-    _virtalElementInfo = [NSMutableDictionary new];
+    _virtualElementInfo = [NSMutableDictionary new];
     if (self.attributes[@"ref"]) {
         NSMutableDictionary *subInfo = [NSMutableDictionary new];
         [self _componentInfoOfRef:self subInfo:subInfo data:data];
@@ -580,23 +593,28 @@ - (void)_recursiveSlotComponent:(WXComponent *)component 
subInfo:(NSMutableDicti
         [self _componentInfoOfRef:subcomponent subInfo:subInfo data:data];
     }
     if (subInfo.count !=0) {
-        [_virtalElementInfo setObject:subInfo forKey:@"refs"];
+        [_virtualElementInfo setObject:subInfo forKey:@"refs"];
     }
 }
 
 - (void)_componentInfoOfRef:(WXComponent *)component 
subInfo:(NSMutableDictionary *)subInfo data:(NSDictionary *)data
 {
     if (component.attributes[@"ref"]) {
-        NSIndexPath *indexPath = data[@"item"][@"indexPath"];
-        NSUInteger position = [indexPath indexAtPosition:1];
-        NSString *virtalElementInfo = [NSString 
stringWithFormat:@"%@@%lu",component.ref,position];
-        NSDictionary *refInfo = 
@{@"attrs":component.attributes,@"type":component->_type,@"ref":virtalElementInfo,@"[[VirtualElement]]":@"true"};
+        NSIndexPath *indexPath = data[@"indexPath"];
+        if (!indexPath) {
+            if (data[@"aliasKey"]) {
+                id key = data[@"aliasKey"];
+                indexPath = data[key][@"indexPath"];
+            }
+        }
+        NSString *virtualElementInfo = [NSString 
stringWithFormat:@"%@@%lu",component.ref,indexPath.row];
+        NSDictionary *refInfo = 
@{@"attrs":component.attributes,@"type":component->_type,@"ref":virtualElementInfo,@"[[VirtualElement]]":@"true"};
         if (subInfo[component.attributes[@"ref"]]) {
             [subInfo[component.attributes[@"ref"]] addObject:refInfo];
         }
         else
         {
-            [subInfo setValue:@[refInfo] forKey:component.attributes[@"ref"]];
+            [subInfo setValue:[NSMutableArray arrayWithArray:@[refInfo]] 
forKey:component.attributes[@"ref"]];
         }
     }
 }
diff --git 
a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm 
b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm
index 3fed198d93..1994bb2df8 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.mm
@@ -293,21 +293,13 @@ - 
(void)_updateDataForCellSlotAtIndexPath:(NSIndexPath*)indexPath data:(NSDictio
 
 - (void)updateData:(NSUInteger)index data:(id)data
 {
-    NSMutableArray * newListData = [[_dataManager data] mutableCopy];
+    NSMutableArray *newListData = [[_dataManager data] mutableCopy];
     if (!data && index > [newListData count]) {
         return;
     }
-    NSIndexPath * indexPath = [NSIndexPath indexPathForRow:index inSection:0];
-    NSDictionary * virtualComponentData = [_dataManager 
virtualComponentDataWithIndexPath:indexPath];
-    if ([virtualComponentData[WXBindingOnceIdentify] boolValue]) {
-        return;
-    }
-    
     // TODO: bring the update logic to UpdateManager
     newListData[index] = data;
     [_dataManager updateData:newListData];
-    NSString* virtualComponentId = [_dataManager 
virtualComponentIdWithIndexPath:indexPath];
-    [_dataManager updateVirtualComponentData:virtualComponentId data:data];
     NSMutableDictionary * newData = nil;
     if (![data isKindOfClass:[NSDictionary class]]) {
          newData = [NSMutableDictionary new];
@@ -316,6 +308,7 @@ - (void)updateData:(NSUInteger)index data:(id)data
     }
     newData = [data mutableCopy];
     newData[@"@phase"] = @"update";
+    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
     [self _updateDataForCellSlotAtIndexPath:indexPath data:[newData copy]];
 }
 
@@ -375,63 +368,65 @@ - (void)moveData:(NSUInteger)fromIndex 
toIndex:(NSUInteger)toIndex
     }];
 }
 
-- (void)scrollTo:(NSString *)virtalElementInfo options:(NSDictionary *)options
+- (void)scrollTo:(NSString *)virtualElementInfo options:(NSDictionary *)options
 {
     NSUInteger position = 0;
-    if ([virtalElementInfo isKindOfClass:[NSNumber class]]) {
-        position = [virtalElementInfo integerValue];
+    if ([virtualElementInfo isKindOfClass:[NSNumber class]]) {
+        position = [virtualElementInfo integerValue];
     }
     else
     {
-        if (virtalElementInfo.length == 0) {
+        if (virtualElementInfo.length == 0) {
             return;
         }
-        position = [self _positionForVirtalElementInfo:virtalElementInfo];
+        position = [self _positionForVirtualElementInfo:virtualElementInfo];
     }
     NSIndexPath *toIndexPath = [NSIndexPath indexPathForItem:position 
inSection:0];
     BOOL animated = options[@"animated"] ? [WXConvert 
BOOL:options[@"animated"]] : YES;
     [_collectionView scrollToItemAtIndexPath:toIndexPath 
atScrollPosition:UICollectionViewScrollPositionTop animated:animated];
 }
 
-- (void)scrollToElement:(NSString *)virtalElementInfo options:(NSDictionary 
*)options
+- (void)scrollToElement:(NSString *)virtualElementInfo options:(NSDictionary 
*)options
 {
-    [self scrollTo:virtalElementInfo options:options];
+    [self scrollTo:virtualElementInfo options:options];
 }
 
-- (void)queryElement:(NSString *)virtalElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback
+- (void)queryElement:(NSString *)virtualElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback
 {
-    [self _queryElement:virtalElementInfo cssSelector:cssSelector 
callback:callback isAll:NO];
+    [self _queryElement:virtualElementInfo cssSelector:cssSelector 
callback:callback isAll:NO];
 }
 
-- (void)queryElementAll:(NSString *)virtalElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback
+- (void)queryElementAll:(NSString *)virtualElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback
 {
-    [self _queryElement:virtalElementInfo cssSelector:cssSelector 
callback:callback isAll:YES];
+    [self _queryElement:virtualElementInfo cssSelector:cssSelector 
callback:callback isAll:YES];
 }
 
-- (NSString *)_refForVirtalElementInfo:(NSString *)virtalElementInfo
+- (NSString *)_refForVirtualElementInfo:(NSString *)virtualElementInfo
 {
-    NSArray *stringArray = [virtalElementInfo 
componentsSeparatedByString:@"@"];
-    if (stringArray.count == 2) {
-        return stringArray[0];
+    if ([virtualElementInfo isKindOfClass:[NSString class]]){
+        NSArray *stringArray = [virtualElementInfo 
componentsSeparatedByString:@"@"];
+        if (stringArray.count == 2) {
+            return stringArray[0];
+        }
     }
     return nil;
 }
 
-- (NSUInteger )_positionForVirtalElementInfo:(NSString *)virtalElementInfo
+- (NSUInteger )_positionForVirtualElementInfo:(NSString *)virtualElementInfo
 {
-    NSArray *stringArray = [virtalElementInfo 
componentsSeparatedByString:@"@"];
+    NSArray *stringArray = [virtualElementInfo 
componentsSeparatedByString:@"@"];
     if (stringArray.count == 2) {
         return [stringArray[1] integerValue];
     }
     return 0;
 }
 
-- (void)closest:(NSString *)virtalElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback
+- (void)closest:(NSString *)virtualElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback
 {
     if(callback)
     {
         WXPerformBlockOnComponentThread(^{
-            WXComponent *component = [self.weexInstance.componentManager 
componentForRef:[self _refForVirtalElementInfo:virtalElementInfo]];
+            WXComponent *component = [self.weexInstance.componentManager 
componentForRef:[self _refForVirtualElementInfo:virtualElementInfo]];
             if (component) {
                 callback([self _closestComponentForCSSSelector:cssSelector 
component:component]);
             }
@@ -455,12 +450,12 @@ - (NSDictionary 
*)_closestComponentForCSSSelector:(NSString *)cssSelector compon
     }
 }
 
-- (void)_queryElement:(NSString *)virtalElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback isAll:(BOOL)isAll
+- (void)_queryElement:(NSString *)virtualElementInfo cssSelector:(NSString 
*)cssSelector callback:(WXModuleCallback)callback isAll:(BOOL)isAll
 {
     if(callback)
     {
         WXPerformBlockSyncOnComponentThread(^{
-            WXComponent *component = [self.weexInstance.componentManager 
componentForRef:[self _refForVirtalElementInfo:virtalElementInfo]];
+            WXComponent *component = [self.weexInstance.componentManager 
componentForRef:[self _refForVirtualElementInfo:virtualElementInfo]];
             if (component) {
                 NSMutableArray *infoArray = [NSMutableArray new];
                 [self _matchComponentForCSSSelector:cssSelector 
component:component infoArray:infoArray];
@@ -636,7 +631,7 @@ - (UICollectionViewCell *)collectionView:(UICollectionView 
*)collectionView cell
     // 2. get the template type specified by data, and if template is not 
found, return an empty view of any template to avoid crash.
     NSString * templateType = [self templateType:indexPath];
     _templateManager.collectionView = collectionView;
-    if (!templateType || (templateType && ![_templateManager 
isTemplateRegistered:templateType])) {
+    if (!templateType) {
         WXLogError(@"Template %@ not registered for collection view.", 
templateType);
         UICollectionViewCell *cellView = [_collectionView 
dequeueReusableCellWithReuseIdentifier:[_templateManager anyRegisteredTemplate] 
forIndexPath:indexPath];
         for (UIView *view in cellView.contentView.subviews) {
@@ -646,6 +641,9 @@ - (UICollectionViewCell *)collectionView:(UICollectionView 
*)collectionView cell
         [cellView setAccessibilityIdentifier:nil];
         return cellView;
     }
+    if (![_templateManager isTemplateRegistered:templateType]) {
+        templateType = @"default";
+    }
     
     // 3. dequeue a cell component by template type
     UICollectionViewCell *cellView = [_collectionView 
dequeueReusableCellWithReuseIdentifier:templateType forIndexPath:indexPath];
diff --git 
a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h 
b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h
index 0a5641e454..9f133f1f1a 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h
@@ -25,6 +25,10 @@
 
 - (void)updateData:(NSArray *)data;
 
+- (void)updateVirtualComponentData:(NSString *)componentId data:(NSDictionary 
*)data;
+
+- (void)deleteVirtualComponentAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths;
+
 - (NSArray *)data;
 
 - (NSDictionary *)dataAtIndex:(NSInteger)index;
@@ -33,13 +37,10 @@
 
 - (NSInteger)numberOfVirtualComponent;
 
-- (NSDictionary*)virtualComponentDataWithId:(NSString*)componentId;
+- (NSDictionary *)virtualComponentDataWithId:(NSString *)componentId;
 
-- (void)updateVirtualComponentData:(NSString*)componentId 
data:(NSDictionary*)data;
+- (NSDictionary *)virtualComponentDataWithIndexPath:(NSIndexPath *)indexPath 
templateId:(NSString *)templateId;
 
-- (NSDictionary*)virtualComponentDataWithIndexPath:(NSIndexPath*)indexPath;
+- (NSString *)virtualComponentIdWithIndexPath:(NSIndexPath *)indexPath 
templateId:(NSString *)templateId;
 
-- (NSString*)virtualComponentIdWithIndexPath:(NSIndexPath*)indexPath;
-
-- (void)deleteVirtualComponentAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths;
 @end
diff --git 
a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m 
b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m
index 5f6f1fca0b..9603f0329e 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m
@@ -26,7 +26,7 @@ @implementation WXRecycleListDataManager
 {
     NSArray *_data;
     NSMapTable<NSString*, NSDictionary*>* _virtualComponentData;
-    NSMapTable<NSIndexPath*, NSString*>*  _renderStatus;
+    NSMapTable<NSIndexPath*, NSMutableSet*>* _renderStatus;
 }
 
 - (instancetype)init
@@ -79,21 +79,20 @@ - (NSInteger)numberOfItems
     return [_data count];
 }
 
-- (void)updateVirtualComponentData:(NSString*)componentId 
data:(NSDictionary*)data
+- (void)updateVirtualComponentData:(NSString *)componentId data:(NSDictionary 
*)data
 {
     if (!componentId) {
         return;
     }
-    NSIndexPath * indexPath = [data objectForKey:@"indexPath"];
     [_virtualComponentData setObject:data forKey:componentId];
-    [_renderStatus setObject:componentId forKey:indexPath];
-    
-//    NSMutableDictionary* newComponentData = [[_virtualComponentData 
objectForKey:componentId] mutableCopy];
-//    if (newComponentData) {
-//        [newComponentData addEntriesFromDictionary:data];
-//    } else {
-//        newComponentData = [data mutableCopy];
-//    }
+
+    NSIndexPath *indexPath = [data objectForKey:@"indexPath"];
+    NSMutableSet *ids = [_renderStatus objectForKey:indexPath];
+    if (!ids) {
+        ids = [NSMutableSet set];
+    }
+    [ids addObject:componentId];
+    [_renderStatus setObject:ids forKey:indexPath];
 }
 
 - (void)deleteVirtualComponentAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths
@@ -102,21 +101,32 @@ - 
(void)deleteVirtualComponentAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths
     [_renderStatus removeAllObjects];
 }
 
-- (NSDictionary*)virtualComponentDataWithId:(NSString*)componentId
+- (NSDictionary *)virtualComponentDataWithId:(NSString *)componentId
 {
     return [_virtualComponentData objectForKey:componentId];
 }
 
-- (NSString*)virtualComponentIdWithIndexPath:(NSIndexPath*)indexPath
+- (NSString *)virtualComponentIdWithIndexPath:(NSIndexPath *)indexPath 
templateId:(NSString *)templateId
 {
-    return [_renderStatus objectForKey:indexPath];
+    if (!templateId) {
+        return nil;
+    }
+    NSSet *ids = [_renderStatus objectForKey:indexPath];
+    if (!ids) {
+        return nil;
+    }
+    for (NSString *componentId in ids) {
+        if ([componentId containsString:templateId]) {
+            return componentId;
+        }
+    }
+    return nil;
 }
 
-- (NSDictionary*)virtualComponentDataWithIndexPath:(NSIndexPath*)indexPath
+- (NSDictionary *)virtualComponentDataWithIndexPath:(NSIndexPath*)indexPath 
templateId:(NSString *)templateId
 {
-    NSString * componentDataId = [self 
virtualComponentIdWithIndexPath:indexPath];
-    
-    return [self virtualComponentDataWithId:componentDataId];
+    NSString *componentId = [self virtualComponentIdWithIndexPath:indexPath 
templateId:templateId];
+    return [self virtualComponentDataWithId:componentId];
 }
 
 - (NSInteger)numberOfVirtualComponent
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h 
b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
index 0735ac2f27..a0371473e4 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -140,7 +140,7 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL 
*needUpdate);
     NSString *_repeatIndexIdentify;
     NSString *_repeatLabelIdentify;
     NSString *_virtualComponentId;// for recycleList subcomponent
-    NSMutableDictionary *_virtalElementInfo;
+    NSMutableDictionary *_virtualElementInfo;
 
     BOOL _isRepeating;
     BOOL _isSkipUpdate;
@@ -260,9 +260,9 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL 
*needUpdate);
 
 - (void)_didInserted;
 
-- (void)_attachSlotEvent:(NSDictionary *)data;
+- (void)attachSlotEvent:(NSDictionary *)data;
 
-- (void)_detachSlotEvent:(NSDictionary *)data;
+- (void)detachSlotEvent:(NSDictionary *)data;
 
 - (void)_buildViewHierarchyLazily;
 
diff --git a/ios/sdk/WeexSDK/Sources/Display/WXComponent+Display.m 
b/ios/sdk/WeexSDK/Sources/Display/WXComponent+Display.m
index 2523bf898b..d5d63b78f5 100644
--- a/ios/sdk/WeexSDK/Sources/Display/WXComponent+Display.m
+++ b/ios/sdk/WeexSDK/Sources/Display/WXComponent+Display.m
@@ -572,7 +572,7 @@ - (BOOL)_bitmapOpaqueWithSize:(CGSize)size
 - (CAShapeLayer *)drawBorderRadiusMaskLayer:(CGRect)rect
 {
     if ([self hasBorderRadiusMaskLayer]) {
-        UIBezierPath *bezierPath = [UIBezierPath 
wx_bezierPathWithRoundedRect:rect topLeft:_borderTopLeftRadius 
topRight:_borderTopRightRadius bottomLeft:_borderBottomLeftRadius 
bottomRight:_borderBottomLeftRadius];
+        UIBezierPath *bezierPath = [UIBezierPath 
wx_bezierPathWithRoundedRect:rect topLeft:_borderTopLeftRadius 
topRight:_borderTopRightRadius bottomLeft:_borderBottomLeftRadius 
bottomRight:_borderBottomRightRadius];
         CAShapeLayer *maskLayer = [CAShapeLayer layer];
         maskLayer.path = bezierPath.CGPath;
         return maskLayer;
diff --git a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m 
b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
index 069b66b0d8..3a059f6685 100644
--- a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
+++ b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
@@ -152,11 +152,12 @@ - (void)fireEvent:(NSString *)eventName 
params:(NSDictionary *)params domChanges
     if (params) {
         [dict addEntriesFromDictionary:params];
     }
-    WXRecycleListComponent * recyleListComponent  = 
(WXRecycleListComponent*)[self getRecycleListComponent];
+    WXRecycleListComponent *recyleListComponent  = 
(WXRecycleListComponent*)[self getRecycleListComponent];
     if (recyleListComponent) {
-        NSIndexPath * indexPath = 
[((UICollectionView*)recyleListComponent.view) 
indexPathForItemAtPoint:[self.view.superview
+        NSIndexPath *indexPath = 
[((UICollectionView*)recyleListComponent.view) 
indexPathForItemAtPoint:[self.view.superview
                                                                                
                           convertPoint:self.view.center 
toView:recyleListComponent.view]];
-        NSString * virtualComponentId = [recyleListComponent.dataManager 
virtualComponentIdWithIndexPath:indexPath];
+        NSString *templateId = [self 
recursiveFindTemplateIdWithComponent:self];
+        NSString *virtualComponentId = [recyleListComponent.dataManager 
virtualComponentIdWithIndexPath:indexPath templateId:templateId];
         if (virtualComponentId) {
             dict[@"componentId"] = virtualComponentId;
         }
@@ -168,6 +169,20 @@ - (void)fireEvent:(NSString *)eventName 
params:(NSDictionary *)params domChanges
     [[WXSDKManager bridgeMgr] fireEvent:self.weexInstance.instanceId ref:ref 
type:eventName params:dict domChanges:domChanges 
handlerArguments:handlerArguments];
 }
 
+- (NSString *)recursiveFindTemplateIdWithComponent:(WXComponent *)component
+{
+    if (!component) {
+        return nil;
+    }
+    if ([component isKindOfClass:NSClassFromString(@"WXCellSlotComponent")]) {
+        return nil;
+    }
+    if (component.attributes[@"@templateId"]) {
+        return component.attributes[@"@templateId"];
+    }
+    return [self 
recursiveFindTemplateIdWithComponent:component.supercomponent];
+}
+
 - (void)addEvent:(NSString *)addEventName
 {
     WXAssertMainThread();
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm 
b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
index 5681183081..1be920fb6d 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
@@ -320,6 +320,7 @@ - (void)setDisplayType:(WXDisplayType)displayType
         if (displayType == WXDisplayTypeNone) {
             _isNeedJoinLayoutSystem = NO;
             [self.supercomponent _recomputeCSSNodeChildren];
+            [self _removeFromSupercomponent];
             WXPerformBlockOnMainThread(^{
                 [self removeFromSuperview];
             });
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m 
b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
index ba8c10fee5..bf1e15b3c9 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
@@ -198,7 +198,7 @@ - (void)getComponentRect:(NSString*)ref 
callback:(WXModuleKeepAliveCallback)call
         } else {
             WXComponent *component = [manager componentForRef:ref];
             dispatch_async(dispatch_get_main_queue(), ^{
-                UIView* rootView = manager.weexInstance.rootView;
+                UIView *rootView = manager.weexInstance.rootView;
                 NSMutableDictionary * callbackRsp = nil;
                 if (!component) {
                     callbackRsp = [NSMutableDictionary new];
@@ -231,8 +231,8 @@ - (void)updateComponentData:(NSString*)componentDataId 
componentData:(NSDictiona
         return;
     }
     SEL selector = _cmd;
-    [self performBlockOnComponentManager:^(WXComponentManager * manager) {
-        WXRecycleListComponent * recycleListComponent = 
(WXRecycleListComponent*)[manager componentForRef:recycleListComponentRef];
+    [self performBlockOnComponentManager:^(WXComponentManager *manager) {
+        WXRecycleListComponent *recycleListComponent = 
(WXRecycleListComponent*)[manager componentForRef:recycleListComponentRef];
         
((void*(*)(id,SEL,NSString*,NSDictionary*,NSString*))objc_msgSend)(recycleListComponent,
 selector, componentDataId, componentData,callbackId);
     }];
 }
@@ -247,7 +247,7 @@ - (void)destroyInstance
 - (NSMutableDictionary*)_componentRectInfoWithViewFrame:(CGRect)componentRect
 {
     CGFloat scaleFactor = self.weexInstance.pixelScaleFactor;
-    NSMutableDictionary * callbackRsp = [NSMutableDictionary new];
+    NSMutableDictionary *callbackRsp = [NSMutableDictionary new];
     [callbackRsp setObject:@{
                              @"width":@(componentRect.size.width /scaleFactor),
                              @"height":@(componentRect.size.height / 
scaleFactor),


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


> refactoring recycle list's data structure and bug-fix
> -----------------------------------------------------
>
>                 Key: WEEX-577
>                 URL: https://issues.apache.org/jira/browse/WEEX-577
>             Project: Weex
>          Issue Type: Improvement
>            Reporter: qz
>            Assignee: Adam Feng
>            Priority: Major
>




--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to