You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ac...@apache.org on 2018/02/09 11:24:25 UTC
incubator-weex git commit: * [iOS] use the first cell-slot template
while the templateType is not specified
Repository: incubator-weex
Updated Branches:
refs/heads/master 7984b16c7 -> e31458ac3
* [iOS] use the first cell-slot template while the templateType is not specified
* [iOS] support componentHook callJS method
* [iOS] create life-cycle for recycle-list component
* [iOS] support lifecycle about create, destroy, attach and detach
* [iOS] fix compiler complains
* [iOS] use switch and case for template selection
* [iOS] remove unused code
* [iOS] update read default case
* [iOS] support lifecycle for recycleList component
close #1023
* [iOS] add component method for operating data
* [iOS] bugfix
* [iOS] rename @componentId to @templateId
* [iOS] support v-once
* [iOS] support non-object in javaScript on data
* [iOS] bugfix about insertRange on recycleList
* [iOS] formate data
* [iOS] add recycleListComponentRef for data
* [iOS] fix bug about v-once
* [iOS] log interrupt update info
* [iOS] bugfix about parse member property
* [iOS] bugfix about recyle-list
* [iOS] update playground version
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/e31458ac
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/e31458ac
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/e31458ac
Branch: refs/heads/master
Commit: e31458ac334446a1d83a8c424676bc8961bc960e
Parents: 7984b16
Author: acton393 <zh...@gmail.com>
Authored: Mon Dec 25 17:54:49 2017 +0800
Committer: acton393 <zh...@gmail.com>
Committed: Fri Feb 9 19:23:33 2018 +0800
----------------------------------------------------------------------
ios/playground/WeexDemo/Info.plist | 4 +-
.../WeexSDK/Sources/Bridge/WXBridgeContext.h | 3 +
.../WeexSDK/Sources/Bridge/WXBridgeContext.m | 27 +++
.../Component/RecycleList/WXCellSlotComponent.h | 3 +-
.../Component/RecycleList/WXCellSlotComponent.m | 7 +-
.../RecycleList/WXComponent+DataBinding.h | 2 +-
.../RecycleList/WXComponent+DataBinding.mm | 89 ++++++-
.../Component/RecycleList/WXJSASTParser.mm | 3 +-
.../RecycleList/WXRecycleListComponent.h | 11 +-
.../RecycleList/WXRecycleListComponent.m | 236 ++++++++++++++-----
.../RecycleList/WXRecycleListDataManager.h | 11 +
.../RecycleList/WXRecycleListDataManager.m | 56 +++++
.../RecycleList/WXRecycleListTemplateManager.h | 2 +
.../RecycleList/WXRecycleListTemplateManager.m | 14 +-
.../RecycleList/WXRecycleListUpdateManager.m | 5 -
.../Component/Recycler/WXRecyclerComponent.m | 1 -
.../Sources/Component/WXComponent_internal.h | 2 +
.../WeexSDK/Sources/Events/WXComponent+Events.m | 25 ++
.../WeexSDK/Sources/Manager/WXBridgeManager.h | 9 +
.../WeexSDK/Sources/Manager/WXBridgeManager.m | 14 ++
.../Sources/Manager/WXComponentManager.m | 4 +-
ios/sdk/WeexSDK/Sources/Model/WXComponent.m | 3 +
ios/sdk/WeexSDK/Sources/Module/WXDomModule.m | 16 ++
.../Sources/View/WXComponent+ViewManagement.m | 4 +
24 files changed, 468 insertions(+), 83 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/playground/WeexDemo/Info.plist
----------------------------------------------------------------------
diff --git a/ios/playground/WeexDemo/Info.plist b/ios/playground/WeexDemo/Info.plist
index 6fd3e06..5ee55ec 100644
--- a/ios/playground/WeexDemo/Info.plist
+++ b/ios/playground/WeexDemo/Info.plist
@@ -26,7 +26,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>2.0</string>
+ <string>2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
@@ -39,7 +39,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
- <string>2</string>
+ <string>3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
index 8ef129f..b3b66b6 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.h
@@ -18,6 +18,7 @@
*/
#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JavaScriptCore.h>
@class WXCallJSMethod;
@class WXSDKInstance;
@@ -122,4 +123,6 @@
**/
- (void)resetEnvironment;
+- (void)callJSMethod:(NSString *)method args:(NSArray *)args onContext:(JSContext*)context completion:(void (^)(JSValue * value))complection;
+
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
index 5af88a0..af473cf 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
@@ -557,6 +557,33 @@ _Pragma("clang diagnostic pop") \
[self performSelector:@selector(_sendQueueLoop) withObject:nil];
}
+- (void)callJSMethod:(NSString *)method args:(NSArray *)args onContext:(JSContext*)context completion:(void (^)(JSValue * value))complection
+{
+ NSMutableArray *newArg = nil;
+ if (!context) {
+ if ([self.jsBridge isKindOfClass:[WXJSCoreBridge class]]) {
+ context = [(NSObject*)_jsBridge valueForKey:@"jsContext"];
+ }
+ }
+ if (self.frameworkLoadFinished) {
+ newArg = [args mutableCopy];
+ if ([newArg containsObject:complection]) {
+ [newArg removeObject:complection];
+ }
+ WXLogDebug(@"Calling JS... method:%@, args:%@", method, args);
+ JSValue *value = [[context globalObject] invokeMethod:method withArguments:args];
+ if (complection) {
+ complection(value);
+ }
+ } else {
+ newArg = [args mutableCopy];
+ if (complection) {
+ [newArg addObject:complection];
+ }
+ [_methodQueue addObject:@{@"method":method, @"args":[newArg copy]}];
+ }
+}
+
- (void)executeAllJsService
{
for(NSDictionary *service in _jsServiceQueue) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h
index 4e62676..e3721be 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.h
@@ -20,9 +20,10 @@
#import <Foundation/Foundation.h>
#import "WXComponent.h"
+static const NSString *WXDefaultRecycleTemplateType = @"default";
@interface WXCellSlotComponent : WXComponent
-@property (nonatomic, strong) NSString *templateType;
+@property (nonatomic, strong) NSString *templateCaseType;
- (void)updateCellData:(NSDictionary *)data;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.m
index 0cbd97b..a6adec0 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXCellSlotComponent.m
@@ -25,8 +25,6 @@
#import "WXAssert.h"
#import "WXScrollerComponent.h"
-static const NSString *WXDefaultRecycleTemplateType = @"WXDefaultRecycleTemplateType";
-
@implementation WXCellSlotComponent
- (instancetype)initWithRef:(NSString *)ref
@@ -39,7 +37,10 @@ static const NSString *WXDefaultRecycleTemplateType = @"WXDefaultRecycleTemplate
self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
if (self) {
// TODO: isRecycle / insertAnimation / deleteAnimation / keepScrollPosition
- _templateType = attributes[@"templateType"] ? [WXConvert NSString:attributes[@"templateType"]] : WXDefaultRecycleTemplateType;
+ if (attributes[@"default"]) {
+ _templateCaseType = @"default";
+ }
+ _templateCaseType = attributes[@"case"] ? [WXConvert NSString:attributes[@"case"]] : WXDefaultRecycleTemplateType;
_lazyCreateView = YES;
_isNeedJoinLayoutSystem = NO;
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.h
index 971252a..b68b159 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.h
@@ -22,10 +22,10 @@
static const NSString *WXBindingIdentify = @"@binding";
static const NSString *WXBindingMatchIdentify = @"[[match]]";
static const NSString *WXBindingRepeatIdentify = @"[[repeat]]";
+static const NSString *WXBindingOnceIdentify = @"[[once]]";
static const NSString *WXBindingRepeatExprIdentify = @"@expression";
static const NSString *WXBindingRepeatIndexIdentify = @"@index";
static const NSString *WXBindingRepeatLabelIdentify = @"@alias";
@interface WXComponent (DataBinding)
-
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
index aad49da..aeb6a36 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXComponent+DataBinding.mm
@@ -21,8 +21,13 @@
#import "WXComponent_internal.h"
#import "WXSDKInstance_private.h"
#import "WXComponentManager.h"
+#import "WXSDKManager.h"
#import "WXAssert.h"
#import "WXJSASTParser.h"
+#import "WXBridgeManager.h"
+#import "WXUtility.h"
+#import "WXRecycleListComponent.h"
+#import "WXRecycleListDataManager.h"
#import <JavaScriptCore/JavaScriptCore.h>
@@ -43,7 +48,30 @@ static JSContext *jsContext;
- (void)updateBindingData:(NSDictionary *)data
{
WXAssertComponentThread();
+ NSString * listRef = nil;
+ NSIndexPath *indexPath = nil;
+ NSDictionary * dictionary = nil;
+ listRef = data[@"recycleListComponentRef"];
+ indexPath = data[@"indexPath"];
+ NSString *phase = data[@"@phase"];
+ if (!indexPath || !listRef) {
+ if (data[@"aliasKey"]) {
+ id key = data[@"aliasKey"];
+ dictionary = data[key];
+ } else {
+ dictionary = data;
+ }
+ listRef = dictionary[@"recycleListComponentRef"];
+ indexPath = dictionary[@"indexPath"];
+ }
+ if (!phase && dictionary) {
+ phase = dictionary[@"@phase"];
+ }
+ if (!indexPath || !listRef) {
+ return;
+ }
+ WXRecycleListComponent * recycleListComponent = (WXRecycleListComponent*)[self.weexInstance.componentManager componentForRef:listRef];
if (_isSkipUpdate) {
_isSkipUpdate = NO;
return;
@@ -62,7 +90,7 @@ static JSContext *jsContext;
}
if (templateComponent->_bindingProps) {
- NSMutableDictionary *newData = [NSMutableDictionary dictionary];
+ __block NSMutableDictionary *newData = [NSMutableDictionary dictionary];
[templateComponent->_bindingProps enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, WXDataBindingBlock _Nonnull block, BOOL * _Nonnull stop) {
BOOL needUpdate;
id value = block(data, &needUpdate);
@@ -71,9 +99,43 @@ static JSContext *jsContext;
}
}];
+ if (self.attributes[@"@isComponentRoot"]) {
+ if (![recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath]) {
+ static NSUInteger __componentId = 0;
+ self->_virtualComponentId = [NSString stringWithFormat:@"%@@%ld", listRef, __componentId % (2048*1024)];
+ __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 toDictionary][@"0"]];
+ [newData setObject:indexPath forKey:@"indexPath"];
+ [newData setObject:listRef forKey:@"recycleListComponentRef"];
+ [[recycleListComponent dataManager] updateVirtualComponentData:self->_virtualComponentId data:newData];
+ dispatch_semaphore_signal(semaphore);
+ }];
+ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
+
+ [[WXSDKManager bridgeMgr] callComponentHook:self.weexInstance.instanceId componentId:self->_virtualComponentId type:@"lifecycle" hook:@"attach" args:nil competion:nil];
+ if ([newData count]) {
+ data = newData;
+ }
+ } else {
+ newData[@"componentDataId"] = self->_virtualComponentId;
+ NSDictionary * virtualComponentData = [recycleListComponent.dataManager virtualComponentDataWithIndexPath:indexPath];
+ [newData addEntriesFromDictionary:virtualComponentData];
+ [newData addEntriesFromDictionary:data];
+ data = newData;
+ }
+ }
+ }
+ if (phase) {
+ NSMutableDictionary * newData = [data mutableCopy];
+ newData[@"@phase"] = phase;
data = newData;
}
-
+ if (self->_templateComponent && self->_templateComponent->_dataBindOnce && recycleListComponent && data[@"@phase"]) {
+ WXLogInfo(@"interrupt update data: %@ because of v-once ", data);
+ return;
+ }
if (!_isRepeating) {
WXDataBindingBlock repeatBlock = templateComponent->_bindingRepeat;
if (repeatBlock) {
@@ -126,12 +188,16 @@ static JSContext *jsContext;
[self.weexInstance.componentManager updateAttributes:newAttributesOrStyles forComponent:self.ref];
} else if (i == WXDataBindingTypeEvents) {
[self _addEventParams:newAttributesOrStyles];
+ } else if (i == WXDataBindingTypeProp) {
}
}
}
NSArray *subcomponents = self.subcomponents;
for (WXComponent *subcomponent in subcomponents) {
+ if (subcomponent->_virtualComponentId &&dictionary[@"componentDataId"] && ![subcomponent->_virtualComponentId isEqualToString:dictionary[@"componentDataId"]]) {
+ continue;
+ }
[subcomponent updateBindingData:data];
}
}
@@ -289,7 +355,9 @@ static JSContext *jsContext;
}
if (type == WXDataBindingTypeAttributes) {
- if ([WXBindingMatchIdentify isEqualToString:name]) {
+ if ([WXBindingOnceIdentify isEqualToString:name]) {
+ _dataBindOnce = [WXConvert BOOL:binding];
+ } else if ([WXBindingMatchIdentify isEqualToString:name]) {
WXJSASTParser *parser = [WXJSASTParser parserWithScript:binding];
WXJSExpression *expression = [parser parseExpression];
_bindingMatch = [self bindingBlockWithExpression:expression];
@@ -323,7 +391,7 @@ static JSContext *jsContext;
*needUpdate = NO;
return nil;
} else if (expression->is<WXJSIdentifier>()) {
- NSString *identiferName = [NSString stringWithCString:(((WXJSIdentifier *)expression)->name).c_str() encoding:[NSString defaultCStringEncoding]];
+ NSString *identiferName = [NSString stringWithCString:const_cast<char*>((((WXJSIdentifier *)expression)->name).c_str()) encoding:NSUTF8StringEncoding];
if (data[identiferName]) {
*needUpdate = YES;
return data[identiferName];
@@ -344,9 +412,16 @@ static JSContext *jsContext;
return [object objectAtIndex:[propertyName unsignedIntegerValue]];
}
} else {
- NSString *propertyName = [NSString stringWithCString:(((WXJSStringLiteral *)member->property)->value).c_str() encoding:[NSString defaultCStringEncoding]];
- *needUpdate = objectNeedUpdate;
- return object[propertyName];
+ WXJSExpression * memberExpression = member->property;
+ if (memberExpression->is<WXJSIdentifier>()) {
+ NSString *propertyName = [NSString stringWithCString:(((WXJSStringLiteral *)member->property)->value).c_str() encoding:[NSString defaultCStringEncoding]];
+ *needUpdate = objectNeedUpdate;
+ return object[propertyName];
+ } else {
+ id retvalue = [self bindingBlockWithExpression:member->property](object, &objectNeedUpdate);
+ *needUpdate = objectNeedUpdate || propertyNeedUpdate;
+ return retvalue;
+ }
}
return nil;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm
index 7e7a565..0be6647 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm
@@ -826,10 +826,9 @@ static int binaryPrecedence(WXJSToken *token)
- (WXJSExpression *)parseMemberExpression
{
WXJSExpression *expr = [self parsePrimaryExpression];
-
if ([self match:"."]) {
[self expect:"."];
- WXJSExpression *property = [self parsePrimaryExpression];
+ WXJSExpression * property = [self parseMemberExpression];
WXJSMemberExpression *memberExpr = new WXJSMemberExpression();
memberExpr->object = expr;
memberExpr->property = property;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h
index a072752..e4be617 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.h
@@ -20,6 +20,15 @@
#import <Foundation/Foundation.h>
#import "WXScrollerComponent.h"
-@interface WXRecycleListComponent : WXScrollerComponent
+@class WXRecycleListDataManager;
+@class WXRecycleListTemplateManager;
+@class WXRecycleListUpdateManager;
+
+@interface WXRecycleListComponent : WXScrollerComponent
+
+@property(nonatomic, strong) WXRecycleListDataManager *dataManager;
+@property(nonatomic, strong) WXRecycleListTemplateManager *templateManager;
+@property(nonatomic, strong) WXRecycleListUpdateManager *updateManager;
+
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.m
index 71a52f5..03f233a 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListComponent.m
@@ -29,6 +29,9 @@
#import "WXRecycleListDataManager.h"
#import "WXRecycleListTemplateManager.h"
#import "WXRecycleListUpdateManager.h"
+#import "WXBridgeManager.h"
+#import "WXSDKManager.h"
+#import "WXComponent+DataBinding.h"
@interface WXRecycleListComponent () <WXRecycleListLayoutDelegate, WXRecycleListUpdateDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
@@ -36,11 +39,7 @@
@implementation WXRecycleListComponent
{
- WXRecycleListDataManager *_dataManager;
- WXRecycleListTemplateManager *_templateManager;
- WXRecycleListUpdateManager *_updateManager;
-
- NSString *_templateKey;
+ NSString *_templateSwitchKey;
NSString *_aliasKey;
NSString *_indexKey;
__weak UICollectionView *_collectionView;
@@ -52,11 +51,14 @@
}
WX_EXPORT_METHOD(@selector(appendData:))
-WX_EXPORT_METHOD(@selector(insertData:atIndex:))
-WX_EXPORT_METHOD(@selector(updateData:atIndex:))
-WX_EXPORT_METHOD(@selector(removeData:))
+WX_EXPORT_METHOD(@selector(appendRange:))
+WX_EXPORT_METHOD(@selector(insertData:data:))
+WX_EXPORT_METHOD(@selector(updateData:data:))
+WX_EXPORT_METHOD(@selector(removeData:count:))
WX_EXPORT_METHOD(@selector(moveData:toIndex:))
WX_EXPORT_METHOD(@selector(scrollTo:options:))
+WX_EXPORT_METHOD(@selector(insertRange:range:))
+WX_EXPORT_METHOD(@selector(setListData:))
- (instancetype)initWithRef:(NSString *)ref
type:(NSString *)type
@@ -66,11 +68,11 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
weexInstance:(WXSDKInstance *)weexInstance
{
if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
- _dataManager = [[WXRecycleListDataManager alloc] initWithData:attributes[@"listData"]];
+ _dataManager = attributes[@"listData"]? [[WXRecycleListDataManager alloc] initWithData:attributes[@"listData"]] : [WXRecycleListDataManager new];
_templateManager = [WXRecycleListTemplateManager new];
_updateManager = [WXRecycleListUpdateManager new];
_updateManager.delegate = self;
- _templateKey = [WXConvert NSString:attributes[@"templateKey"]] ? : @"templateType";
+ _templateSwitchKey = [WXConvert NSString:attributes[@"switch"]];
_aliasKey = [WXConvert NSString:attributes[@"alias"]];
_indexKey = [WXConvert NSString:attributes[@"index"]];
_sizeCache = [NSMutableDictionary dictionary];
@@ -120,6 +122,15 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
NSArray *listData = attributes[@"listData"];
[self _updateListData:listData withCompletion:nil animation:NO];
}
+ if (attributes[@"switch"]) {
+ _templateSwitchKey = [WXConvert NSString:attributes[@"switch"]];
+ }
+ if (attributes[@"alias"]) {
+ _aliasKey = [WXConvert NSString:attributes[@"alias"]];
+ }
+ if (attributes[@"index"]) {
+ _indexKey = [WXConvert NSString:attributes[@"index"]];
+ }
}
- (CGPoint)absolutePositionForComponent:(WXComponent *)component
@@ -179,18 +190,33 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
#pragma mark - Exported Component Methods
-- (void)appendData:(NSArray *)appendingData
+- (void)appendData:(id)appendingData
{
- if (![appendingData isKindOfClass:[NSArray class]]) {
- WXLogError(@"wrong format of appending data:%@", appendingData);
+ if (!appendingData){
+ return;
+ }
+ NSMutableArray * newListData = [[_dataManager data] mutableCopy];
+ [newListData addObject:appendingData];
+}
+
+- (void)appendRange:(NSArray*)data
+{
+ if (![data isKindOfClass:[NSArray class]]) {
+ WXLogError(@"wrong format of appending data:%@", data);
return;
}
NSArray *oldData = [_dataManager data];
- [_updateManager updateWithAppendingData:appendingData oldData:oldData completion:nil animation:NO];
+ [_updateManager updateWithAppendingData:data oldData:oldData completion:nil animation:NO];
}
-- (void)insertData:(id)data atIndex:(NSUInteger)index
+- (void)setListData:(NSArray*)data
+{
+ if ([data count]) {
+ [_dataManager updateData:data];
+ }
+}
+- (void)insertData:(NSUInteger)index data:(id)data
{
// TODO: bring the update logic to UpdateManager
// TODO: update cell because index has changed
@@ -202,47 +228,110 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];
[UIView performWithoutAnimation:^{
- [_collectionView insertItemsAtIndexPaths:@[indexPath]];
+ [self->_collectionView insertItemsAtIndexPaths:@[indexPath]];
}];
}
}
-- (void)updateData:(id)data atIndex:(NSUInteger)index
+- (void)updateComponentData:(NSString*)componentDataId componentData:(NSDictionary*)componentData callback:(NSString*)callbackId
{
- // TODO: bring the update logic to UpdateManager
- NSMutableArray *newListData = [[_dataManager data] mutableCopy];
- if (index < newListData.count) {
- newListData[index] = data;
- [_dataManager updateData:newListData];
-
- NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];
- UICollectionViewCell *cellView = [_collectionView cellForItemAtIndexPath:indexPath];
- WXCellSlotComponent *cellComponent = (WXCellSlotComponent *)cellView.wx_component;
- if (cellComponent) {
- [self _updateBindingData:data forCell:cellComponent atIndexPath:indexPath];
+ NSMutableDictionary * virtualComponentData = [[_dataManager virtualComponentDataWithId:componentDataId] mutableCopy];
+ NSIndexPath * indexPath = virtualComponentData[@"indexPath"];
+ if (!indexPath) {
+ return;
+ }
+ virtualComponentData = virtualComponentData?:[NSMutableDictionary new];
+ [virtualComponentData addEntriesFromDictionary:componentData];
+ [_dataManager updateVirtualComponentData:componentDataId data:[virtualComponentData copy]];
+ virtualComponentData[@"@phase"] = @"update";
+ virtualComponentData[@"callbackId"] = callbackId;
+ [self _updateDataForCellSlotAtIndexPath:indexPath data:virtualComponentData];
+}
+
+- (void)_updateDataForCellSlotAtIndexPath:(NSIndexPath*)indexPath data:(NSDictionary*)data
+{
+ if(!indexPath || !data) {
+ return;
+ }
+ WXPerformBlockOnMainThread(^{
+ UICollectionViewCell * cellView = [self->_collectionView cellForItemAtIndexPath:indexPath];
+ WXCellSlotComponent * cellSlotComponent = (WXCellSlotComponent*)cellView.wx_component;
+ if (cellSlotComponent) {
+ [self _updateBindingData:data forCell:cellSlotComponent atIndexPath:indexPath];
}
+ // callback when update virtual component data success.
+ NSString * callbackId = data[@"callbackId"];
+ if (callbackId) {
+ [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:callbackId params:@{@"result":@"success"}];
+ }
+ });
+}
+
+- (void)updateData:(NSUInteger)index data:(id)data
+{
+ 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];
+ [newData setObject:@"data" forKey:data];
+ data = newData;
+ }
+ newData = [data mutableCopy];
+ newData[@"@phase"] = @"update";
+ [self _updateDataForCellSlotAtIndexPath:indexPath data:[newData copy]];
+}
+
+- (void)insertRange:(NSInteger)index range:(NSArray*)data
+{
+ if (![data count]) {
+ WXLogDebug(@"ignore invalid insertRange");
+ return;
}
+
+ NSMutableArray * newListData = [[_dataManager data] mutableCopy];
+ NSRange range = NSMakeRange(index,[data count]);
+ NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
+ [newListData insertObjects:data atIndexes:indexSet];
+ [_dataManager updateData:newListData];
+ [_collectionView reloadData];
}
-- (void)removeData:(NSArray *)indexes
+- (void)removeData:(NSInteger)index count:(NSInteger)count
{
// TODO: bring the update logic to UpdateManager
+
NSMutableArray *newListData = [[_dataManager data] mutableCopy];
- NSMutableIndexSet *indexSet = [NSMutableIndexSet new];
- NSMutableArray *indexPaths = [NSMutableArray array];
- for (NSNumber *index in indexes) {
- if ([index unsignedIntegerValue] >= newListData.count) {
- WXLogError(@"invalid remove index:%@", index);
- continue;
- }
- [indexSet addIndex:[index unsignedIntegerValue]];
- [indexPaths addObject:[NSIndexPath indexPathForItem:[index unsignedIntegerValue] inSection:0]];
+ if (index > [newListData count] || index + count - 1 > [newListData count]) {
+
+ return;
}
-
+ NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, count)];
[newListData removeObjectsAtIndexes:indexSet];
+ __block NSMutableArray<NSIndexPath*>* indexPaths = [NSMutableArray new];
+ [indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
+ NSIndexPath* indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
+ [indexPaths addObject:indexPath];
+ }];
+
[_dataManager updateData:newListData];
+ [_dataManager deleteVirtualComponentAtIndexPaths:indexPaths];
[UIView performWithoutAnimation:^{
- [_collectionView deleteItemsAtIndexPaths:indexPaths];
+ [self->_collectionView deleteItemsAtIndexPaths:indexPaths];
+ [self->_collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
}];
}
@@ -258,7 +347,7 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
NSIndexPath *fromIndexPath = [NSIndexPath indexPathForItem:fromIndex inSection:0];
NSIndexPath *toIndexPath = [NSIndexPath indexPathForItem:toIndex inSection:0];
[UIView performWithoutAnimation:^{
- [_collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
+ [self->_collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
}];
}
@@ -287,11 +376,30 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
#pragma mark - Private
-- (void)_updateBindingData:(NSDictionary *)data forCell:(WXCellSlotComponent *)cellComponent atIndexPath:(NSIndexPath *)indexPath
+- (void)_updateBindingData:(id)data forCell:(WXCellSlotComponent *)cellComponent atIndexPath:(NSIndexPath *)indexPath
{
- if (_aliasKey) {
- data = @{_aliasKey:data};
+ id originalData = data;
+ if (![originalData isKindOfClass:[NSDictionary class]]) {
+ if (_aliasKey) {
+ NSMutableDictionary * dictionary = [NSMutableDictionary dictionary];
+ [dictionary setObject:data forKey:_aliasKey];
+ data = dictionary;
+ } else {
+ return;
+ }
+ }
+
+ if (!data[@"indexPath"] || !data[@"recycleListComponentRef"]) {
+ NSMutableDictionary * dataNew = [data mutableCopy];
+ dataNew[@"recycleListComponentRef"] = self.ref;
+ dataNew[@"indexPath"] = indexPath;
+ data = dataNew;
}
+
+ if ([originalData isKindOfClass:[NSDictionary class]] && _aliasKey &&!data[@"phase"]) {
+ data = @{_aliasKey:data,@"aliasKey":_aliasKey};
+ }
+
if (_indexKey) {
NSMutableDictionary *dataNew = [data mutableCopy];
dataNew[_indexKey] = @(indexPath.item);
@@ -301,8 +409,9 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
#ifdef DEBUG
NSDate *startTime = [NSDate date];
#endif
+
WXPerformBlockSyncOnComponentThread(^{
- [cellComponent updateCellData:data];
+ [cellComponent updateCellData:[data copy]];
});
#ifdef DEBUG
double duration = -[startTime timeIntervalSinceNow] * 1000;
@@ -350,16 +459,13 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// 1. get the data relating to the cell
- NSDictionary *data = [_dataManager dataAtIndex:indexPath.row];
- if (!data || ![data isKindOfClass:[NSDictionary class]]) {
- WXLogError(@"No data or wrong data format for index:%zd, data:%@", indexPath.item, data);
- return nil;
- }
+ id data = [_dataManager dataAtIndex:indexPath.row];
// 2. get the template type specified by data
- NSString *templateType = data[_templateKey];
+ NSString * templateType = [self templateType:indexPath];
+ _templateManager.collectionView = collectionView;
if (!templateType) {
- WXLogError(@"Each data should have a value for %@ to indicate template type", _templateKey);
+ WXLogError(@"Each data should have a value for %@ to indicate template type", _templateSwitchKey);
return nil;
}
@@ -392,9 +498,7 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
WXLogDebug(@"Return cell view:%@, indexPath:%@", cellView, indexPath);
- dispatch_async(dispatch_get_main_queue(), ^{
- [self handleAppear];
- });
+ [self handleAppear];
return cellView;
}
@@ -424,8 +528,8 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
if (size) {
return [size CGSizeValue];
} else {
- NSDictionary *data = [_dataManager dataAtIndex:indexPath.row];
- WXCellSlotComponent *cell = [_templateManager templateWithType:data[_templateKey]];
+
+ WXCellSlotComponent *cell = [_templateManager templateWithType:[self templateType:indexPath]];
CGSize size = cell.calculatedFrame.size;
_sizeCache[indexPath] = [NSValue valueWithCGSize:size];
return CGSizeMake(_collectionView.frame.size.width, size.height);
@@ -456,4 +560,22 @@ WX_EXPORT_METHOD(@selector(scrollTo:options:))
}
+- (NSString*)templateType:(NSIndexPath*)indexPath
+{
+ NSDictionary *data = [_dataManager dataAtIndex:indexPath.row];
+ // default is first template.
+ NSString *templateType = [_templateManager topTemplate].templateCaseType;
+ if (!data || ![data isKindOfClass:[NSDictionary class]]) {
+ return templateType;
+ }
+
+ if (_templateSwitchKey &&data[_templateSwitchKey]){
+ templateType = data[_templateSwitchKey];
+ } else if (data[WXDefaultRecycleTemplateType]){
+ // read the default type.
+ templateType = data[WXDefaultRecycleTemplateType];
+ }
+ return templateType;
+}
+
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h
index fc053c5..0a5641e 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.h
@@ -31,4 +31,15 @@
- (NSInteger)numberOfItems;
+- (NSInteger)numberOfVirtualComponent;
+
+- (NSDictionary*)virtualComponentDataWithId:(NSString*)componentId;
+
+- (void)updateVirtualComponentData:(NSString*)componentId data:(NSDictionary*)data;
+
+- (NSDictionary*)virtualComponentDataWithIndexPath:(NSIndexPath*)indexPath;
+
+- (NSString*)virtualComponentIdWithIndexPath:(NSIndexPath*)indexPath;
+
+- (void)deleteVirtualComponentAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths;
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m
index 8d27171..5f6f1fc 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListDataManager.m
@@ -25,6 +25,17 @@
@implementation WXRecycleListDataManager
{
NSArray *_data;
+ NSMapTable<NSString*, NSDictionary*>* _virtualComponentData;
+ NSMapTable<NSIndexPath*, NSString*>* _renderStatus;
+}
+
+- (instancetype)init
+{
+ if (self = [super init]) {
+ _virtualComponentData = [NSMapTable strongToStrongObjectsMapTable];
+ _renderStatus = [NSMapTable strongToStrongObjectsMapTable];
+ }
+ return self;
}
- (instancetype)initWithData:(NSArray *)data
@@ -68,4 +79,49 @@
return [_data count];
}
+- (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];
+// }
+}
+
+- (void)deleteVirtualComponentAtIndexPaths:(NSArray<NSIndexPath*>*)indexPaths
+{
+ [_virtualComponentData removeAllObjects];
+ [_renderStatus removeAllObjects];
+}
+
+- (NSDictionary*)virtualComponentDataWithId:(NSString*)componentId
+{
+ return [_virtualComponentData objectForKey:componentId];
+}
+
+- (NSString*)virtualComponentIdWithIndexPath:(NSIndexPath*)indexPath
+{
+ return [_renderStatus objectForKey:indexPath];
+}
+
+- (NSDictionary*)virtualComponentDataWithIndexPath:(NSIndexPath*)indexPath
+{
+ NSString * componentDataId = [self virtualComponentIdWithIndexPath:indexPath];
+
+ return [self virtualComponentDataWithId:componentDataId];
+}
+
+- (NSInteger)numberOfVirtualComponent
+{
+ return [_virtualComponentData count];
+}
+
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h
index 389dbb8..926c2f1 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.h
@@ -30,4 +30,6 @@
- (WXCellSlotComponent *)templateWithType:(NSString *)type;
+- (WXCellSlotComponent *)topTemplate;
+
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m
index 87ecd90..199d551 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListTemplateManager.m
@@ -62,7 +62,7 @@
{
WXAssertMainThread();
- NSString *templateType = component.templateType;
+ NSString *templateType = component.templateCaseType;
WXAssert(templateType != nil, @"cell-slot:%@ must have a template id!", component);
[_templateTypeMap setObject:component forKey:templateType];
@@ -91,4 +91,16 @@
[_collectionView registerClass:[WXReusableCollectionViewCell class] forCellWithReuseIdentifier:templateID];
}
+- (WXCellSlotComponent *)topTemplate
+{
+ WXCellSlotComponent * cellTemplate = nil;
+ for (NSString *templateType in [_templateTypeMap.keyEnumerator.allObjects copy]) {
+ cellTemplate = [self templateWithType:templateType];
+ if (!cellTemplate) {
+ break;
+ }
+ }
+ return cellTemplate;
+}
+
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m
index cdeae05..d500895 100644
--- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m
+++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXRecycleListUpdateManager.m
@@ -208,11 +208,6 @@
NSMutableSet<NSIndexPath *> *deleteIndexPaths = [NSMutableSet set];
NSMutableSet<NSIndexPath *> *insertIndexPaths = [NSMutableSet set];
- for (WXDiffUpdateIndex *update in diffResult.updates) {
- NSIndexPath *reloadIndexPath = [NSIndexPath indexPathForItem:update.oldIndex inSection:0];
- [reloadIndexPaths addObject:reloadIndexPath];
- }
-
[diffResult.updates enumerateObjectsUsingBlock:^(WXDiffUpdateIndex * _Nonnull update, NSUInteger idx, BOOL * _Nonnull stop) {
NSIndexPath *reloadIndexPath = [NSIndexPath indexPathForItem:update.oldIndex inSection:0];
[reloadIndexPaths addObject:reloadIndexPath];
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/Recycler/WXRecyclerComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/Recycler/WXRecyclerComponent.m b/ios/sdk/WeexSDK/Sources/Component/Recycler/WXRecyclerComponent.m
index be4d7a6..aa4bf1a 100644
--- a/ios/sdk/WeexSDK/Sources/Component/Recycler/WXRecyclerComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/Recycler/WXRecyclerComponent.m
@@ -124,7 +124,6 @@ typedef enum : NSUInteger {
if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
[self _fillPadding];
-
if ([type isEqualToString:@"waterfall"] || (attributes[@"layout"] && [attributes[@"layout"] isEqualToString:@"multi-column"])) {
// TODO: abstraction
_layoutType = WXRecyclerLayoutTypeMultiColumn;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
index eddbfe7..c8c7b5b 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -146,8 +146,10 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
WXDataBindingBlock _bindingRepeat;
NSString *_repeatIndexIdentify;
NSString *_repeatLabelIdentify;
+ NSString *_virtualComponentId;// for recycleList subcomponent
BOOL _isRepeating;
BOOL _isSkipUpdate;
+ BOOL _dataBindOnce;
NSMutableDictionary<NSString *, WXDataBindingBlock> *_bindingProps;
NSMutableDictionary<NSString *, WXDataBindingBlock> *_bindingAttributes;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
index 5747fe4..621df21 100644
--- a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
+++ b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
@@ -26,6 +26,10 @@
#import "WXUtility.h"
#import "WXSDKManager.h"
#import "WXSDKInstance_private.h"
+#import "WXDefine.h"
+#import "WXRecycleListComponent.h"
+#import "WXRecycleListDataManager.h"
+
#import <objc/runtime.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
#import "WXComponent+PseudoClassManagement.h"
@@ -108,6 +112,15 @@
if (params) {
[dict addEntriesFromDictionary:params];
}
+ WXRecycleListComponent * recyleListComponent = (WXRecycleListComponent*)[self getRecycleListComponent];
+ if (recyleListComponent) {
+ NSIndexPath * indexPath = [((UICollectionView*)recyleListComponent.view) indexPathForItemAtPoint:[self.view.superview
+ convertPoint:self.view.center toView:recyleListComponent.view]];
+ NSString * virtualComponentId = [recyleListComponent.dataManager virtualComponentIdWithIndexPath:indexPath];
+ if (virtualComponentId) {
+ dict[@"componentId"] = virtualComponentId;
+ }
+ }
NSArray *handlerArguments = [self _paramsForEvent:eventName];
NSString *ref = _templateComponent ? _templateComponent.ref : self.ref;
@@ -714,6 +727,18 @@ if ([removeEventName isEqualToString:@#eventName]) {\
return resultTouch;
}
+// find virtual component's root component
+- (WXComponent*)getRecycleListComponent
+{
+ if ([self isKindOfClass:[WXRecycleListComponent class]]) {
+ return self;
+ }
+ if ([self.ref isEqualToString:WX_SDK_ROOT_REF]) {
+ return nil;
+ }
+ return [self.supercomponent getRecycleListComponent];
+}
+
@end
@implementation WXTouchGestureRecognizer
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
index 77fec46..9d7cece 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
@@ -18,6 +18,7 @@
*/
#import <Foundation/Foundation.h>
+#import <JavaScriptCore/JavaScriptCore.h>
@class WXBridgeMethod;
@class WXSDKInstance;
@@ -142,6 +143,14 @@ extern void WXPerformBlockOnBridgeThread(void (^block)(void));
- (void)fireEvent:(NSString *)instanceId ref:(NSString *)ref type:(NSString *)type params:(NSDictionary *)params domChanges:(NSDictionary *)domChanges handlerArguments:(NSArray *)handlerArguments;
/**
+ * componentHook
+ * @param instanceId : instance id
+ * @param componentId : compoent id
+ * @param type : component hook Type, such as life-cycle
+ * @param hookPhase : hook phase
+ */
+- (void)callComponentHook:(NSString*)instanceId componentId:(NSString*)componentId type:(NSString*)type hook:(NSString*)hookPhase args:(NSArray*)args competion:(void (^)(JSValue * value))complection;
+/**
* callBack
*
* @param instanceId instanceId
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
index 896bed7..c77bdde 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
@@ -326,6 +326,20 @@ void WXPerformBlockOnBridgeThread(void (^block)(void))
[self callJsMethod:method];
}
+- (void)callComponentHook:(NSString*)instanceId componentId:(NSString*)componentId type:(NSString*)type hook:(NSString*)hookPhase args:(NSArray*)args competion:(void (^)(JSValue * value))complection
+{
+ WXPerformBlockOnBridgeThread(^{
+ if (!type || !instanceId || !hookPhase) {
+ WXLogError(@"type and instance id and hookPhase should not be nil");
+ return;
+ }
+ NSArray *newArgs = @[componentId, type, hookPhase, args?:@[]];
+
+ WXCallJSMethod * method = [[WXCallJSMethod alloc] initWithModuleName:nil methodName:@"componentHook" arguments:newArgs instance:[WXSDKManager instanceForID:instanceId]];
+ [self.bridgeCtx callJSMethod:@"callJS" args:@[instanceId, @[method.callJSTask]] onContext:nil completion:complection];
+ });
+}
+
- (void)callBack:(NSString *)instanceId funcId:(NSString *)funcId params:(id)params keepAlive:(BOOL)keepAlive
{
NSArray *args = nil;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m
index 446e01c..1413402 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m
@@ -429,7 +429,6 @@ static css_node_t * rootNodeGetChild(void *context, int i)
Class clazz = NSClassFromString(config.clazz);;
WXComponent *component = [[clazz alloc] initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:self.weexInstance];
-
if (isTemplate) {
component->_isTemplate = YES;
[component _storeBindingsWithProps:bindingProps styles:bindingStyles attributes:bindingAttibutes events:bindingEvents];
@@ -460,7 +459,8 @@ static css_node_t * rootNodeGetChild(void *context, int i)
[attributesOrStyles enumerateKeysAndObjectsUsingBlock:^(id _Nonnull attributeOrStyleName, id _Nonnull attributeOrStyle, BOOL * _Nonnull stop) {
if ([WXBindingMatchIdentify isEqualToString:attributeOrStyleName] // match
|| [WXBindingRepeatIdentify isEqualToString:attributeOrStyleName] // repeat
- || ([attributeOrStyle isKindOfClass:[NSDictionary class]] && attributeOrStyle[WXBindingIdentify])) { // {"attributeOrStyleName": {"@binding":"bindingExpression"}
+ || [WXBindingOnceIdentify isEqualToString:attributeOrStyleName] // once
+ ||([attributeOrStyle isKindOfClass:[NSDictionary class]] && attributeOrStyle[WXBindingIdentify])) { // {"attributeOrStyleName": {"@binding":"bindingExpression"}
bindingAttributesOrStyles[attributeOrStyleName] = attributeOrStyle;
[newAttributesOrStyles removeObjectForKey:attributeOrStyleName];
} else if ([attributeOrStyle isKindOfClass:[NSArray class]]) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
index aaf04d1..3f4f1ce 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
@@ -199,6 +199,9 @@
// [self _removeAllEvents];
// remove all gesture and all
+ if (_isTemplate && self.attributes[@"@templateId"]) {
+ [[WXSDKManager bridgeMgr] callComponentHook:_weexInstance.instanceId componentId:self.attributes[@"@templateId"] type:@"lifecycle" hook:@"destroy" args:nil competion:nil];
+ }
if (_tapGesture) {
[_tapGesture removeTarget:nil action:NULL];
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
index edb0597..3b22b84 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXDomModule.m
@@ -28,6 +28,8 @@
#import "WXRuleManager.h"
#import "WXSDKInstance.h"
#import "WXTracingManager.h"
+#import "WXRecycleListComponent.h"
+#import <objc/message.h>
@interface WXDomModule ()
@@ -51,6 +53,7 @@ WX_EXPORT_METHOD(@selector(updateStyle:styles:))
WX_EXPORT_METHOD(@selector(updateAttrs:attrs:))
WX_EXPORT_METHOD(@selector(addRule:rule:))
WX_EXPORT_METHOD(@selector(getComponentRect:callback:))
+WX_EXPORT_METHOD(@selector(updateComponentData:componentData:callback:))
- (void)performBlockOnComponentManager:(void(^)(WXComponentManager *))block
{
@@ -223,6 +226,19 @@ WX_EXPORT_METHOD(@selector(getComponentRect:callback:))
}];
}
+- (void)updateComponentData:(NSString*)componentDataId componentData:(NSDictionary*)componentData callback:(NSString*)callbackId
+{
+ NSString *recycleListComponentRef = [[componentDataId componentsSeparatedByString:@"@"] objectAtIndex:0];
+ if (!recycleListComponentRef) {
+ return;
+ }
+ SEL selector = _cmd;
+ [self performBlockOnComponentManager:^(WXComponentManager * manager) {
+ WXRecycleListComponent * recycleListComponent = (WXRecycleListComponent*)[manager componentForRef:recycleListComponentRef];
+ ((void*(*)(id,SEL,NSString*,NSDictionary*,NSString*))objc_msgSend)(recycleListComponent, selector, componentDataId, componentData,callbackId);
+ }];
+}
+
- (void)destroyInstance
{
[self performBlockOnComponentManager:^(WXComponentManager *manager) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e31458ac/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m
index be27ae7..e066a14 100644
--- a/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m
+++ b/ios/sdk/WeexSDK/Sources/View/WXComponent+ViewManagement.m
@@ -25,6 +25,7 @@
#import "WXSDKInstance_private.h"
#import "WXTransform.h"
#import "WXTracingManager.h"
+#import "WXSDKManager.h"
#define WX_BOARD_RADIUS_RESET_ALL(key)\
do {\
@@ -329,6 +330,9 @@ do {\
}
[_view removeFromSuperview];
+ if (self->_isTemplate && self.attributes[@"@templateId"]) {
+ [[WXSDKManager bridgeMgr] callComponentHook:self.weexInstance.instanceId componentId:self.attributes[@"@templateId"] type:@"lifecycle" hook:@"detach" args:nil competion:nil];
+ }
_view = nil;
[_layer removeFromSuperlayer];
_layer = nil;