You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅将编辑过的非空参数传入服务调用?

如何仅将编辑过的非空参数传入服务调用?

看起来你现在的问题是接口请求时会把所有可选字段(比如fName、mName)都塞进参数里,哪怕是空字符串或者没修改过的,你只想传修改过的非空参数,同时保留那些必填的ID参数对吧?我给你两种适配思路,你可以根据需求选:


方案1:只传「修改过的非空字段」(精准匹配你的需求)

这个方案会跟踪你实际修改过的字段,只把这些字段里有值的部分传到接口,完全符合你“改了哪个传哪个”的要求。

步骤1:在ViewModel里加个“修改跟踪器”

先在你的ViewModel里加一个集合,专门记录哪些profile字段被修改过:

class YourViewModel: ObservableObject {
    @Published var profile: ProfileData? = nil
    // 新增:记录修改过的字段名
    @Published var modifiedProfileFields = Set<String>()
    // ... 其他现有代码
}

步骤2:修改TextField的Binding,标记修改的字段

把每个TextField的set闭包改一下,当字段值真的变化时,把对应的字段名加入跟踪集合:

labeledTextField(
    title: "staffProfile_firstName".localized(),
    placeholder: "staffProfile_firstName".localized(),
    text: Binding(
        get: { viewModel.profile?.fName ?? "" },
        set: { 
            // 先处理空值转nil的逻辑,和你原来的逻辑一致
            let newValue = $0.isEmpty ? nil : $0
            // 只有当值真的变化时,才更新并标记修改
            if viewModel.profile?.fName != newValue {
                viewModel.profile?.fName = newValue
                viewModel.modifiedProfileFields.insert("fName")
            }
        }
    ),
    disabled: false
)

// 同理修改mName、lName等其他TextField的set闭包,对应插入"mName"、"lName"等字段名

步骤3:重构接口参数构建逻辑

在staffUpdateProfile方法里,先放必填的ID参数,再只把跟踪到的、有非空值的字段加进去:

func staffUpdateProfile(titleID: Int, maritialStatusID: Int, relationshipWithMemberId: Int, bloodGroupID: Int, relegionID: Int, nationalityID: Int) async {
    guard APIManager.shared.isConnectedToInternet else {
        showInfoToast(message: "No internet connection.")
        return
    }
    let url = APIEndPoint.userSendStaffProfileRequest
    
    // 1. 先初始化必填的ID参数,这些是必须传的
    var params: [String: Any] = [
        "titleID": titleID,
        "maritialStatusID": maritialStatusID,
        "relationshipWithMemberId": relationshipWithMemberId,
        "bloodGroupID": bloodGroupID,
        "relegionID": relegionID,
        "nationalityID": nationalityID
    ]
    
    // 2. 把所有可选字段的键和对应值存成数组,方便遍历
    let optionalFields: [(key: String, value: Any?)] = [
        ("fName", profile?.fName),
        ("mName", profile?.mName),
        ("lName", profile?.lName),
        ("mobile", profile?.mobile),
        ("alternateMobile", profile?.alternateMobile)
    ]
    
    // 3. 只把「修改过的」且「非空」的字段加入参数
    for field in optionalFields {
        if modifiedProfileFields.contains(field.key), let fieldValue = field.value {
            params[field.key] = fieldValue
        }
    }
    
    // ... 后面的接口请求逻辑不变,记得更新成功后清空跟踪集合
    do {
        let model: CommonModel = try await APIManager.shared.asyncCallDecodableApiRequest(
            with: url,
            method: .post,
            params: params,
            showHud: true
        )
        if model.status == "ok" {
            showSuccessToast(message: model.message ?? "Profile updated successfully.")
            self.isProfileDataEdited = false
            // 重置跟踪集合,下次修改重新记录
            self.modifiedProfileFields.removeAll()
        } else {
            showErrorToast(message: model.message ?? "Update failed.")
        }
    } catch {
        await showInfoToastOnMainAction(message: error.localizedDescription)
    }
}

方案2:传「所有非空字段」(更简单,适合不需要精准跟踪修改的场景)

如果你其实不在乎是否修改过,只是不想传空字符串或者nil的参数,那这个方案更简单:直接遍历所有可选字段,只把有值的加进参数里就行,不用跟踪修改记录。

修改staffUpdateProfile里的参数构建部分:

func staffUpdateProfile(titleID: Int, maritialStatusID: Int, relationshipWithMemberId: Int, bloodGroupID: Int, relegionID: Int, nationalityID: Int) async {
    guard APIManager.shared.isConnectedToInternet else {
        showInfoToast(message: "No internet connection.")
        return
    }
    let url = APIEndPoint.userSendStaffProfileRequest
    
    // 1. 先放必填参数
    var params: [String: Any] = [
        "titleID": titleID,
        "maritialStatusID": maritialStatusID,
        "relationshipWithMemberId": relationshipWithMemberId,
        "bloodGroupID": bloodGroupID,
        "relegionID": relegionID,
        "nationalityID": nationalityID
    ]
    
    // 2. 逐个判断可选字段,非空才加入
    if let fName = profile?.fName { params["fName"] = fName }
    if let mName = profile?.mName { params["mName"] = mName }
    if let lName = profile?.lName { params["lName"] = lName }
    if let mobile = profile?.mobile { params["mobile"] = mobile }
    if let alternateMobile = profile?.alternateMobile { params["alternateMobile"] = alternateMobile }
    
    // ... 后面的接口请求逻辑不变
}

这个方案的好处是代码更少,不需要修改TextField的Binding逻辑,适合只要非空就传的场景。


两种方案都能解决你“不传空字符串参数”的问题,方案1更精准匹配你“只传修改过的参数”的需求,方案2更简洁,你可以根据自己的业务场景选~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:03:07